<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Carmine Noviello &#187; Grok</title>
	<atom:link href="http://www.carminenoviello.com/category/grok/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.carminenoviello.com</link>
	<description>ilnovi&#039;s corner</description>
	<lastBuildDate>Mon, 06 Jun 2011 06:00:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Grok tutorial #1: viste e modelli</title>
		<link>http://www.carminenoviello.com/2009/05/20/grok-viste-e-modelli/</link>
		<comments>http://www.carminenoviello.com/2009/05/20/grok-viste-e-modelli/#comments</comments>
		<pubDate>Wed, 20 May 2009 18:17:14 +0000</pubDate>
		<dc:creator>Carmine Noviello</dc:creator>
				<category><![CDATA[Grok]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[modelli]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[viste]]></category>

		<guid isPermaLink="false">http://www.carminenoviello.name/grok/grok-viste-e-modelli</guid>
		<description><![CDATA[Tutti i web framework moderni introducono la nozione di viste e modelli, e forniscono quanto necessario per gestire queste strutture e le loro funzionalit&#224;. Un modello, rappresenta uno o pi&#249; dati logicamente interconnessi fra loro, e fornisce anche tutte le operazioni di manipolazione di questi. Ad esempio, la scheda di anagrafica di un cliente pu&#242; [...]]]></description>
			<content:encoded><![CDATA[<p>Tutti i web framework moderni introducono la nozione di viste e modelli, e forniscono quanto necessario per gestire queste strutture e le loro funzionalit&agrave;.</p>
<p>Un modello, rappresenta uno o pi&ugrave; dati logicamente interconnessi fra loro, e fornisce anche tutte le operazioni di manipolazione di questi. Ad esempio, la scheda di anagrafica di un cliente pu&ograve; essere vista come un modello dell&#39;applicazione. Un&#39;applicazione &egrave; tendenzialmente composta di una serie di modelli, che spesso non svolgono necessariamente il ruolo di contenitori di dati, ma possono svolgere anche altri compiti di servizio per il funzionamento dell&#39;intera applicazione.</p>
<p>Le viste, come il nome suggerisce, sono una rappresentazione dei modelli. Possono esistere viste di diversa natura per gli stessi dati: nei framework web in genere esiste almeno la vista che permette di interagire via HTTP con il modello attraverso la classica pagina web, ma possono esistere anche altre viste non orientate alla fruizione dell&#39;utente (XML, REST, ecc).</p>
<p>Questo modello di progettazione &egrave; una versione pi&ugrave; semplificata del pi&ugrave; generale pattern <a href="http://en.wikipedia.org/wiki/Model-view-controller">Model View Controller</a>, che in aggiunta introduce un ulteriore strato intermedio (il controller) che fissa le regole di interazione tra il modello e le viste associate. Grok spinge sulla versione pi&ugrave; semplificata del pattern MVC ma, come sar&agrave; pi&ugrave; chiaro in avanti, &egrave; perfettamente adottabile una libera progettazione dell&#39;applicazione.</p>
<p><span id="more-70"></span></p>
<p>&nbsp;</p>
<h3>Creazione di un progetto base</h3>
<p>Il primo passo per la costruzione di un&#39;applicazione Grok &egrave; installare le componenti di base del framework. Da oltre un anno la comunit&agrave; Zope ha lavorato pesantemente sulla struttura fisica di Zope 3: molte funzionalit&agrave; sono state spacchettate in moduli <em>self-contained</em>, che spesso possono essere adoperati singolarmente e in totale isolamento dalla restante parte del framework. Grok fa uso di circa un centinaio di questi moduli, ma la gestione della loro installazione &egrave; demandata automaticamente al gestore che configura l&#39;ambiente di esecuzione di un progetto basato su Grok, a sua volta un altro componente sviluppato dalla comunit&agrave;: <a href="http://pypi.python.org/pypi/zc.buildout">zc.buildout</a>.<br />
	Per prima cosa, &egrave; necessario installare il pacchetto <tt>grokproject</tt>, che &egrave; sostanzialmente composto dai template <a href="http://pypi.python.org/pypi/Paste/1.7.2">Paste</a> necessari alla generazione dello scheletro del progetto. Tale operazione pu&ograve; essere effettuata in automatico con l&#39;uso del comando easy_install (con i necessari privilegi di amministrazione):</p>
<p>&nbsp;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ easy_install grokproject
...</pre></div></div>

<p>Terminata questa breve frase, &egrave; possibile generare lo scheletro del progetto ed installare tutti i moduli di dipendenza tramite il comando <tt>buildout</tt>:</p>
<p>&nbsp;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ grokproject testproject
Enter user <span style="color: #7a0874; font-weight: bold;">&#40;</span>Name of an initial administrator user<span style="color: #7a0874; font-weight: bold;">&#41;</span>: admin
Enter <span style="color: #c20cb9; font-weight: bold;">passwd</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>Password <span style="color: #000000; font-weight: bold;">for</span> the initial administrator user<span style="color: #7a0874; font-weight: bold;">&#41;</span>: 
Downloading info about versions...
Creating directory .<span style="color: #000000; font-weight: bold;">/</span>testproject
Downloading zc.buildout...
Invoking zc.buildout...
Develop: <span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #666666; font-style: italic;">#39;/Users/cnoviello/testproject/.&amp;#39;</span>
Installing eggbasket.
ymir:~ cnoviello$ <span style="color: #7a0874; font-weight: bold;">cd</span> testproject<span style="color: #000000; font-weight: bold;">/</span>
ymir:~ cnoviello$ .<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>buildout <span style="color: #660033;">-v</span>
...</pre></div></div>

<p>&nbsp;</p>
<p>Questa fase pu&ograve; avere una durata temporale pi&ugrave; o meno ampia, a seconda della connessione di rete, se si hanno gi&agrave; una serie di pacchetti di base installati, la potenza dell&#39;elaboratore sottostante. Ma cosa avviene esattamente in questa fase? Il modulo<tt> zc.buildout</tt>, a partire dalle direttive contenute all&#39;interno del file <tt>buildout.cfg</tt> nella root del progetto generato, verifica tutte le dipendenze con i moduli necessari al framework e, se non soddisfatte, provvede a scaricare gli <tt>.egg</tt> dai repository ufficiali tramite <a href="http://pypi.python.org">pypi</a>. Tutti questi moduli, tuttavia, non sono resi disponibili a livello globale del sistema, ma sono scaricati per default all&#39;interno della directory <tt>.buildout</tt> della cartella dell&#39;utente che genera il progetto. Questo comportamento di default di Grok, che ha generato diverse <a href="https://bugs.launchpad.net/grok/+bug/330480">discussioni</a> nella comunit&agrave; che ancora non hanno portato ad una posizione comune, implica che progetti diversi, ma in esecuzione sotto lo stesso utente, condividono la stessa istallazione del framework di base di Grok. L&#39;alternativa &egrave; la configurazione di un ambiente di esecuzione isolato per ogni progetto Grok. Esistono due alternative: quella di avere utenti di sistema separati per ogni installazione, o di adoperare <a href="http://pypi.python.org/pypi/virtualenv">virtualenv</a>. Alla fine di questo post troverete una sezione specifica che illustra brevemente quali sono i passi per configurare virtualenv, dato che ho trovato la documentazione ufficiale un po&#39; datata e contraddittoria sull&#39;argomento.<br />
	Infine c&#39;&egrave; un altro aspetto. Esistono sistemi operativi che forniscono supporto diretto all&#39;esecuzione di servizi basati su Zope. Nello specifico mi riferisco ad alcune distribuzioni Linux come Debian e Ubuntu. Per adoperare l&#39;infrastruttura di base messa a disposizione dal sistema (come script di runlevel ed altro) &egrave; preferibile configurare <tt>grokproject</tt> in modo da generare un layout del progetto simile alla classica distribuzione Zope 2. Per fare ci&ograve;, al momento della creazione del progetto basta adoperare il comando:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ grokproject <span style="color: #660033;">--zopectl</span> testproject</pre></div></div>

<h3>Il layout del progetto generato</h3>
<p>Al termine della procedura di buildout si ottiene un progetto Grok minimale pronto sia per essere eseguito sia esteso in base alle esigenze. Come &egrave; possibile notare, <tt>grokproject</tt> ha creato diverse sottodirectory. Le principali sono:</p>
<ul>
<li><tt>bin</tt>: contiene tutti gli script e gli eseguibili necessari all&#39;esecuzione dell&#39;application server Zope, alla base di Grok;</li>
<li><tt>parts</tt>: formato da diverse sottodirectory che contengono file di configurazione, percorsi di log e dati dell&#39;applicazione;</li>
<li><tt>src</tt>: la sottodirectory contenente l&#39;egg della nostra applicazione. Tutti i file sorgenti saranno posizionali al suo interno, e resi disponibili in automatico nei percorsi dell&#39;interprete all&#39;atto del caricamento dell&#39;application server.</li>
</ul>
<p>Per mandare in esecuzione l&#39;application server, &egrave; sufficiente digitare il comando:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ .<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>testproject-ctl start</pre></div></div>

<p>Per default, l&#39;application server girer&agrave; sulla porta 8080: nel caso di esigenze particolari &egrave; possibile specificare una porta diversa modificando il file <tt>parts/etc/deploy.ini </tt>nella sezione<tt> [server:main]</tt>.Posizionandosi con il browser sull&#39;indirizzo <a href="http://localhost:8080">http://localhost:8080</a>, una volta digitate le credenziali scelte alla creazione del progetto, &egrave; possibile accedere alla consolle di gestione di Grok, e creare un&#39;istanza dell&#39;applicazione di prova creata da <tt>grokproject</tt>. Per chi gi&agrave; conosce Zope tutte queste operazioni risulteranno molto familiari. In alternativa, ho creato un piccolo screencast per mostrare questa operazione.</p>
<p>&nbsp;</p>
<div><object height="505" width="640"><param name="movie" value="http://www.youtube.com/v/wrVO-SdCStg&amp;hl=it&amp;fs=1&amp;hd=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed allowfullscreen="true" allowscriptaccess="always" height="505" src="http://www.youtube.com/v/wrVO-SdCStg&amp;hl=it&amp;fs=1&amp;hd=1" type="application/x-shockwave-flash" width="640"></embed></object></div>
<p>&nbsp;</p>
<h3>L&#39;applicazione generata</h3>
<p>L&#39;applicazione generata da grokproject si trova all&#39;interno della directory <tt>src/testproject/</tt>, e contiene i seguenti file e sottodirectory:</p>
<ul>
<li><tt>app.py</tt>: &egrave; il file principale contenente lo scheletro dell&#39;applicazione;</li>
<li><tt>app_templates</tt>: &egrave; la directory contenente tutti i template associati alle viste definite all&#39;interno del file <tt>app.py</tt>; per convenzione, Grok associa a tutte le viste definite in file <tt>nomefile.py</tt> i template presenti nella sottodirectory <tt>nomefile_templates</tt>;</li>
<li><tt>configure.zcml</tt>: contiene le direttive ZCML per configurare i componenti di Grok;</li>
<li><tt>static</tt>: contiene tutti i file &quot;statici&quot; dell&#39;applicazione, quali immagini, fogli di stile, script, ecc.</li>
</ul>
<p>All&#39;interno del file <tt>app.py</tt> si trova lo scheletro dell&#39;applicazione generata:</p>
<p>&nbsp;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> grok
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Testproject<span style="color: black;">&#40;</span>grok.<span style="color: black;">Application</span>, grok.<span style="color: black;">Container</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Index<span style="color: black;">&#40;</span>grok.<span style="color: black;">View</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span> <span style="color: #808080; font-style: italic;"># see app_templates/index.pt</span></pre></td></tr></table></div>

<p>Sembra quasi incredibile che questo frammento di codice cos&igrave; piccolo sia sufficiente a generare un&#39;applicazione web in piena regola. Vediamo nel dettaglio. Alla riga 3 viene definita la classe <tt>Testproject</tt>, che rappresenta la classe principale della nostra applicazione: non a caso eredita da <tt>grok.Application</tt>. <tt>Testproject</tt> &egrave; anche una classe contenitore (eredita da <tt>grok.Container</tt>): questo significa che &egrave; in grado di ospitare al suo interno istanze di altri modelli. Gi&agrave;, perch&eacute; il fatto che <tt>Testproject</tt> erediti da <tt>grok.Container</tt>, implica che siamo alla presenza di una classe che &egrave; un modello della nostra applicazione. Infine, alla riga 6 viene definita la vista per la classe <tt>Testproject</tt>: sar&agrave; in automatico Grok, che all&#39;atto della partenza dell&#39;application server &quot;grokker&agrave;&quot; la classe <tt>Index</tt> associandone l&#39;istanza alla istanza della classe <tt>Testproject</tt>, che &egrave; creata da noi attraverso l&#39;interfaccia di amministrazione di Grok (come riportato nello screencast di esempio). Grok, inoltre, si preoccupa anche di associare in automatico il template presente nella sottodirectory <tt>app_templates</tt>, che per convenzione deve avere lo stesso nome della classe vista.</p>
<p>Proviamo a rendere l&#39;applicazione di test pi&ugrave; sofisticata, realizzando un&#39;applicazione che permette l&#39;inserimento di brevi note. Innanzitutto, abbiamo bisogno di una classe che modella il concetto di nota. Questo pu&ograve; essere ottenuto con un codice molto elementare simile al seguente:</p>
<p>&nbsp;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Note<span style="color: black;">&#40;</span>grok.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, note<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>Note, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">note</span> = note
        <span style="color: #008000;">self</span>.<span style="color: black;">when</span> = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Si parte con la definizione di una classe <tt>Note</tt>, che eredita da<tt> grok.Model</tt>: questo implica definire un nuovo modello dell&#39;applicazione. Nel costruttore della classe viene da prima invocato il costruttore della superclasse (operazione sempre necessaria quando si eredita da classi di base di Grok), dopo di che si imposta l&#39;attributo <tt>note</tt>, che contiene la nota, e l&#39;attributo <tt>when</tt>, che indica la data e l&#39;ora del momento di inserimento della nota.<br />
	Definito il modello, &egrave; necessario creare una semplice vista per mostrare all&#39;utente il contenuto della nota:&nbsp;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> NoteView<span style="color: black;">&#40;</span>grok.<span style="color: black;">View</span><span style="color: black;">&#41;</span>:
    grok.<span style="color: black;">context</span><span style="color: black;">&#40;</span>Note<span style="color: black;">&#41;</span>
    grok.<span style="color: black;">name</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">&amp;</span><span style="color: #808080; font-style: italic;">#39;index&amp;#39;)</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> dt.<span style="color: black;">fromtimestamp</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">context</span>.<span style="color: black;">when</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Essendo <tt>NoteView</tt> una vista deve ereditare da <tt>grok.View</tt>, la superclasse delle viste Grok. Con la direttiva <tt>grok.context()</tt> eseguiamo l&#39;associazione tra la vista e la classe modello: in questo modo, sar&agrave; sempre possibile accedere nel codice della vista al modello tramite l&#39;attributo <tt>self.context</tt> (chi conosce Zope 3 ha gi&agrave; capito che <tt>grok.View </tt>&egrave; una comune <tt>BrowserView</tt> di Zope 3 e la direttiva <tt>grok.context</tt> permette di specificare la classe dell&#39;oggetto adattato). Con la direttiva <tt>grok.name() </tt>si specifica il nome della vista, ossia l&#39;url da specificare per visualizzare la vista specifica. Per default, se<tt> grok.name() </tt>non viene specificato, il nome della vista corrisponde al nome della classe vista in lowercase, ossia <tt>nota/noteview</tt>; specificando <tt>grok.name(&#39;index&#39;) </tt>non stiamo facendo altro che specificare la vista di default per un oggetto di tipo <tt>Note</tt>. Infine, il metodo <tt>time() </tt>restituisce un oggetto <tt>datetime</tt> a partire dal <em>timestamp</em> della funzione<tt> time.time()</tt>.<br />
	All&#39;oggetto vista &egrave; associato un piccolo template <a href="http://docs.zope.org/zope2/zope2book/source/AppendixC.html">ZPT</a> (il linguaggio di templating di Zope), che ha lo stesso nome della classe <tt>NoteView</tt> ed &egrave; posizionato all&#39;interno della directory <tt>app_templates</tt>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">...</pre></td></tr></table></div>

<p>Nota inserita il:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&nbsp;</pre></td></tr></table></div>

<p tal:content="context/note">&nbsp;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">...</pre></td></tr></table></div>

<p>Nella riga 2 di questo frammento di codice non si fa altro che invocare il metodo<tt> time()</tt> della classe <tt>NoteView</tt>: in un template ZPT con <tt>view</tt> si fa sempre automaticamente riferimento alla vista. Nella riga successiva, tramite il riferimento <tt>context</tt> al modello associato alla vista, ricaviamo direttamente il valore del campo <tt>note</tt>, che contiene la nota inserita dall&#39;utente.<br />
	Per quanto riguarda la parte di inserimento della nota, partiamo con il commentare il codice ZPT associato alla classe <tt>Testproject</tt>:</p>
<p>&nbsp;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">...</pre></td></tr></table></div>

<div>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&nbsp;</pre></td></tr></table></div>

<p>Aggiungi una nota!</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&nbsp;</pre></td></tr></table></div>

<form action="." method="post">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">            &lt;input id=&quot;note&quot; name=&quot;note&quot; type=&quot;text&quot; /&gt;
            &lt;input id=&quot;add&quot; name=&quot;add&quot; type=&quot;submit&quot; value=&quot;Aggiungi&quot; /&gt;</pre></td></tr></table></div>

</form>
</div>
<p>&#8230;</p>
<p>Come &egrave; possibile vedere, il codice scritto non &egrave; niente altro che il codice HTML necessario alla gestione di una form di inserimento, con un campo contenente il testo della nota ed un pulsante aggiunti. Tutto il lavoro &egrave; svolto dalla vista <tt>Index</tt>, associata al modello principale <tt>Testproject</tt>:</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Index<span style="color: black;">&#40;</span>grok.<span style="color: black;">View</span><span style="color: black;">&#41;</span>:
    grok.<span style="color: black;">context</span><span style="color: black;">&#40;</span>Testproject<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, note=<span style="color: #008000;">None</span>, add=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> add == <span style="color: #66cc66;">&amp;</span><span style="color: #808080; font-style: italic;">#39;Aggiungi&amp;#39;:</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">context</span>.<span style="color: black;">notecounter</span> += <span style="color: #ff4500;">1</span>
            noteid = <span style="color: #66cc66;">&amp;</span><span style="color: #808080; font-style: italic;">#39;note%d&amp;#39; % self.context.notecounter</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">context</span><span style="color: black;">&#91;</span>noteid<span style="color: black;">&#93;</span> = Note<span style="color: black;">&#40;</span>note<span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">redirect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">url</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">context</span><span style="color: black;">&#91;</span>noteid<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Si comincia con l&#39;associare la vista alle istanze della classe <tt>Testproject</tt> con la direttiva <tt>grok.context()</tt>. Alla riga 4 viene definito il metodo <tt>update()</tt>, che &egrave; invocato ogniqualvolta la vista viene renderizzata. I parametri <tt>note</tt> e <tt>add</tt> corrispondono ai campi della form definita nel codice ZPT mostrato in precedenza. Il corpo del metodo non fa altro che generare un nuovo identificativo per la nota (vi ricordo che <tt>self.context</tt> fa riferimento al modello, e quindi a <tt>Testproject</tt>), e attraverso il codice della linea 8, la nuova nota viene inserita all&#39;interno di <tt>Testproject</tt>, che ereditando da <tt>grok.Container</tt> pu&ograve; memorizzare al suo interno oggetti che sono modelli (in realt&agrave; non solo, ma questo sar&agrave; oggetto di un altro tutorial): <tt>grok.Container</tt> &egrave; una classe che si comporta come un dizionario, permettendo la memorizzazione di oggetti nella forma chiave/valore. Inoltre, gli oggetti contenitori supportano il cosiddetto <em>traversing</em>, ossia la capacit&agrave; di esporre in automatico la loro struttura di annidamento tramite URL HTTP. Ad esempio, una volta inserita una nota, &egrave; possibile visualizzarla all&#39;URL <a href="http://localhost:8080/testproject/note1">http://localhost:8080/testproject/note1</a>.</p>
<p>Tutto il codice di esempio pu&ograve; essere scaricato direttamente da <a href="http://www.carminenoviello.com/wp-content/examples/testproject.tgz">qui</a>. Il pacchetto scaricato va per&ograve; risottoposto al buildout (&egrave; un operazione da fare ogni qualvolta si ridistribuisce il codice dell&#39;applicazione), con i comandi:</p>
<p>&nbsp;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ python bootstrap.py
ymir:~ cnoviello$ .<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>buildout</pre></div></div>

<p>Prossimamente andremo pi&ugrave; nel dettaglio della direttiva<tt> grok.context()</tt>, illustrando i concetti fondativi alla base di Zope 3: la Zope Component Architecture. Nel frattempo vi rimando alla <a href="http://grok.zope.org/documentation">documentazione ufficiale</a> di Grok.</p>
<p>&nbsp;</p>
<h3>*Creare un ambiente di esecuzione isolato con <tt>virtualenv</tt></h3>
<p><a href="http://pypi.python.org/pypi/virtualenv">virtualenv</a> &egrave; il tool per creare ambienti di esecuzione Python isolati dalla configurazione generale di sistema. Questo significa nei fatti creare una configurazione che sovrascriva i path generali della distribuzione di Python, configurando un ambiente minimale all&#39;interno del quale effettuare tutte le necessarie configurazioni, con l&#39;aggiunta dei tool diventati standard nella toolchain di Python, come <tt>easy_install</tt> ed altri. Per creare un progetto Grok isolato &egrave; necessario effettuare una serie di passi preliminari prima della creazione del progetto. Innanzitutto, &egrave; necessario installare <tt>virtualenv</tt> e creare l&#39;ambiente virtuale all&#39;interno del quale sar&agrave; creato il progetto:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ easy_install virtualenv
...
ymir:~ cnoviello$ virtualenv virtualgrok
...</pre></div></div>

<p>Una volta creato l&#39;ambiente &egrave; necessario attivarlo (operazione che implica la sovrascrittura dei PATH generali di python) ogni qualvolta si effettuano operazioni con esso come, ad esempio, creare il progetto Grok che vogliamo isolare o mandarlo in esecuzione. Per attivare o disattivare un ambiente virtuale &egrave; sufficiente digitare i comandi:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ <span style="color: #7a0874; font-weight: bold;">source</span> .<span style="color: #000000; font-weight: bold;">/</span>virtualgrok<span style="color: #000000; font-weight: bold;">/</span>bin activate
...
ymir:~ cnoviello$ deactivate</pre></div></div>

<p>Prima di procedere con la configurazione di grokproject, &egrave; necessario per&ograve; installare Paste:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ymir:~ cnoviello$ <span style="color: #7a0874; font-weight: bold;">source</span> .<span style="color: #000000; font-weight: bold;">/</span>virtualgrok<span style="color: #000000; font-weight: bold;">/</span>bin activate
<span style="color: #7a0874; font-weight: bold;">&#40;</span>virtualgrok<span style="color: #7a0874; font-weight: bold;">&#41;</span>ymir:~ cnoviello$ easy_install Paste PasteScript PasteDeploy
...
<span style="color: #7a0874; font-weight: bold;">&#40;</span>virtualgrok<span style="color: #7a0874; font-weight: bold;">&#41;</span>ymir:~ cnoviello$ easy_install grokproject</pre></div></div>

<p>
	Una volta costruito l&#39;ambiente all&#39;interno di esso sar&agrave; possibile creare il progetto Grok desiderato come descritto in precedenza. A questo punto &egrave; necessaria una precisazione. Questa operazione non implica adoperare una directory separata per la cache dei singoli <tt>.egg</tt> scaricati dal buildout: il buildout continuer&agrave; ad accedere alla sottodirectory <tt>.buildout</tt> contenuta nella home dell&#39;utente. Per isolare anche quest&#39;ultimo aspetto, &egrave; necessario modificare il file <tt>buildout.cfg</tt>, nello specifico nella sezione <tt>[buildout]</tt> aggiungendo la direttiva<tt> eggs-directory</tt>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>buildout<span style="color: #7a0874; font-weight: bold;">&#93;</span>
...
eggs-directory = <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>cnoviello<span style="color: #000000; font-weight: bold;">/</span>virtualgrok<span style="color: #000000; font-weight: bold;">/</span>.buildout<span style="color: #000000; font-weight: bold;">/</span>eggs</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.carminenoviello.com/2009/05/20/grok-viste-e-modelli/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dalla preistoria arriva Grok per il futuro di Zope 3</title>
		<link>http://www.carminenoviello.com/2009/05/02/dalla-preistoria-arriva-grok-per-il-futuro-di-zope-3/</link>
		<comments>http://www.carminenoviello.com/2009/05/02/dalla-preistoria-arriva-grok-per-il-futuro-di-zope-3/#comments</comments>
		<pubDate>Sat, 02 May 2009 11:21:35 +0000</pubDate>
		<dc:creator>Carmine Noviello</dc:creator>
				<category><![CDATA[Grok]]></category>
		<category><![CDATA[pycon]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[zope]]></category>

		<guid isPermaLink="false">http://www.carminenoviello.name/informatica/grok/dalla-preistoria-arriva-grok-per-il-futuro-di-zope-3</guid>
		<description><![CDATA[Alzi la mano chi almeno una volta non ha pensato che Zope non &#232; un framework per lo sviluppo rapido di applicazioni web. E a giudicare dalla proliferazione di prodotti concorrenti (Django, Pylons, Turbogears, ecc), e il loro relativo successo, vuol dire che a fare questa considerazione devono essere stati in molti. Purtroppo questa nomea [...]]]></description>
			<content:encoded><![CDATA[<p>Alzi la mano chi almeno una volta non ha pensato che Zope non &egrave; un framework per lo sviluppo rapido di applicazioni web. E a giudicare dalla proliferazione di prodotti concorrenti (<a href="http://www.djangoproject.com/">Django</a>, <a href="http://pylonshq.com/">Pylons</a>, <a href="http://turbogears.org/">Turbogears</a>, ecc), e il loro relativo successo, vuol dire che a fare questa considerazione devono essere stati in molti.</p>
<p>Purtroppo questa nomea &egrave; ormai ampiamente diffusa, al punto che anche ai vertici della comunit&agrave; si stanno ponendo gi&agrave; da tempo il problema di come rilanciare il prodotto, sia per quanto riguarda <a href="http://regebro.wordpress.com/2009/04/08/pycon-2009-zope-3-is-dead/">Zope</a> sia la sua applicazione pi&ugrave; diffusa: <a href="http://www.martinaspeli.net/articles/is-plone-too-hard">Plone</a>. Gi&agrave;, perch&eacute; forse quest&#8217;ultimo prodotto &egrave; in gran parte responsabile di questa reputazione, essendo molto pi&ugrave; popolare del framework stesso e ed essendo la porta che apre effettivamente la strada al mondo Zope.</p>
<p>Ma qual &egrave; l&#8217;origine di tutto ci&ograve;? Chi conosce Zope e ci lavora da tempo (il sottoscritto da oltre 5 anni) &egrave; ampiamente a conoscenza delle vicissitudini del framework, ma prover&ograve; qui a sintetizzare i punti pi&ugrave; critici.</p>
<p><span id="more-66"></span></p>
<ul>
<li><strong>Zope 2</strong>: il problema principale di Zope &egrave; stato, e rimane, Zope 2. Ebbene, la versione che ha reso celebre Zope &egrave; anche quella che ha sensibilmente contribuito al declino della piattaforma. Un modello di programmazione monolitico, un ciclo di sviluppo troppo pressante che spesso e volentieri ha portato all&#8217;insorgenza di pesanti incompatibilit&agrave; tra una <em>minor revision number</em> ed un&#8217;altra hanno fatto s&igrave; che Zope si &egrave; conquistato l&#8217;appellativo di framework poco <em>pythonico</em>. Ed &egrave; vero. In Zope 2 per sfruttare una singola funzionalit&agrave; eri costretto ad adoperare contemporaneamente l&#8217;intero framework, o poco ci mancava, con pesanti ripercussioni sulla velocit&agrave; di sviluppo, la stabilit&agrave; e longevit&agrave; del codice, la curva di apprendimento (forse Zope &egrave; uno dei pochi strumenti che controbilancia la curva di apprendimento di Python che &egrave; molto bassa).</li>
<li><strong>Zope 2 + 3</strong>: quando la comunit&agrave; ha capito che quel modello di programmazione, basato su un uso abnorme di ereditariet&agrave; e <em>mix-in programming</em>, non avrebbe fatto molta strada, ha cominciato a sviluppare un framework basandolo su un modello di programmazione radicalmente diverso, ossia quello per componenti. Lo sviluppo di Zope 3 risale a molti anni addietro, ma la sua diffusione si &egrave; andata consolidando soltanto di recente e soprattutto quando la comunit&agrave; si &egrave; resa conto che senza una <em>smooth transition</em> nessuno sarebbe mai passato al nuovo mondo. Per questo, si &egrave; cominciato ad importare quel modello di programmazione, e le componenti gi&agrave; sviluppate per Zope 3, in Zope 2, con l&#8217;ausilio di Five. Da quel momento in poi c&#8217;&egrave; stata una sorta di frattura che ha generato solo caos, a mio modo di vedere. Si &egrave; assistito (e lo si vede ancora oggi) a prodotti che presentavano un approccio misto, con codice per met&agrave; a componenti e per met&agrave; alla vecchia maniera. Inoltre, si &egrave; imposto a tutti quelli che seguivano il prodotto un passaggio ad un nuovo modello di sviluppo senza che se ne capisse veramente l&#8217;utilit&agrave; e soprattutto dovendolo far convivere con altro codice che costantemente violava i dettami della programmazione per componenti. Plone, &egrave; l&#8217;esempio pi&ugrave; lampante di questo, e ancora pi&ugrave; emblematiche sono le liste dei requisiti di Plone 3.x e 4.x che sono state costantemente modificate nel tempo spostando in avanti passaggi critici per la migrazione a Zope 3.</li>
<li><strong>Plone</strong>: quando si parla di Zope &egrave; inevitabile accostarlo a Plone, che &egrave; sicuramente il prodotto pi&ugrave; diffuso della piattaforma. Ebbene, Plone &egrave; uno dei principali responsabili del degrado dell&#8217;immagine complessiva di Zope. Anche lui, infatti, presenta delle complessit&agrave; connesse sia sul fronte del progetto complessivo sia per quanto riguarda il target stesso del progetto. Innanzitutto Plone &egrave; un CMS, e in quanto tale si &egrave; evoluto. Questo ha comportato che col tempo il prodotto si &egrave; andato arricchendo di funzionalit&agrave; che lo hanno da un lato reso forse uno dei migliori CMS disponibili, dall&#8217;altro hanno indebolito il fronte della versatilit&agrave; e velocit&agrave; di sviluppo. Se con Plone 2.0 era ancora pensabile sviluppare siti web leggeri e &quot;agili&quot;, oggi &egrave; diventato sempre pi&ugrave; impensabile adoperarlo in questi ambiti sia perch&eacute; richiede tempi di sviluppo ed adattamento notevoli, sia perch&eacute; impone all&#8217;utente finale conoscenze non del tutto di base. Per quanto riguarda lo sviluppo, anche con Plone si &egrave; assistito ad un costante cambiamento che ne ha minato la stabilit&agrave;. Ancora oggi si assiste ad una serie di contraddizioni che sono difficili da comprendere: si &egrave; ormai abbracciata in molti aspetti la filosofia di sviluppo di Zope 3, ma si continua a presentare gli Archetype come la libreria di base per estendere il set dei <em>content-type</em>.</li>
<li><strong>Zope 3</strong>: lo stesso Zope 3, nato per garantire un futuro solido alla piattaforma, ha contribuito al suo indebolimento. Innanzitutto, il modello di programmazione per componenti &egrave; di difficile digestione alla massa dei programmatori python e soprattutto richiede delle esigenze forti per essere adoperato. Se per un framework come Zope pu&ograve; rappresentare la soluzione migliore per migliorare la modularit&agrave; e il riuso del codice (&egrave; una possibile soluzione, ma bisogna ammettere che non &egrave; necessariamente l&#8217;unica in un linguaggio che promuove il <a href="http://en.wikipedia.org/wiki/Duck_typing">duck typing</a>), per un&#8217;applicazione tipo e di dimensione limitata, pensare per componenti pu&ograve; essere una forzatura, e spesso aumenta la complessit&agrave; del codice senza benefici tangibili. Poi, Zope 3 ha introdotto dei cambiamenti che hanno sensibilmente stravolto l&#8217;idea di Zope. Ad esempio, lo sviluppo TTW &egrave; stato ufficialmente bandito (indubbiamente ottima scelta), ma non c&#8217;&egrave; dubbio che la ZMI &egrave; stata una delle parti che ha maggiormente contribuito alla diffusione di Zope 2. Infine, la voglia di modularizzare al massimo ha spinto fin alla modularizzazione e parametrizzazione della fase di configurazione del framework, con l&#8217;introduzione dello ZCML che ha ulteriormente complicato la vita del programmatore medio e molto indaffarato.</li>
<li><strong>ZODB</strong>: l&#8217;ultimo della carrellata (ma non sicuramente per importanza ai fini di questa analisi, anzi&#8230;..) &egrave; il database ad oggetti di Zope. Innanzitutto, far capire ad un cliente che non si ha un database relazionale come Oracle o MySQL &egrave; un&#8217;operazione di una difficolt&agrave; inaudita, e spesso il cliente preferisce ricorrere ad altre soluzioni ma non rinunciare al DBMS. Le ragioni di ci&ograve; sono complesse, ed esulano dallo scopo di questo mio post, ma va detto che per molti aspetti i DBMS relazionali classici continuano ad offrire versatilit&agrave;, scalabilit&agrave; e fruibilit&agrave; maggiore. Poi ci si &egrave; aggiunta la nomea che lo ZODB &egrave; scarsamente performante. In realt&agrave;, non &egrave; cos&igrave;. Soprattutto dalle versioni 3.6 e successive, lo ZODB &egrave; diventato estremamente veloce e affidabile (transazionale, ecc). Quello che continua ad essere scarsamente performante &egrave; il software che lo usa, e spesso stiamo parlando di Plone che per mia esperienza rimane un prodotto molto pesante ed assetato di risorse hardware (sul circuito <a href="http://www.campaniabeniculturali.it/">campaniabeniculturali.it</a> che ospita nodi da 63 portali <a href="http://octapycms.remuna.org/">Octapy</a>, che sono basati su Plone, abbiamo server da 12 o pi&ugrave; GB di RAM che soffrono non poco).</li>
</ul>
<p>Dopo tutto questo sproloquio, pu&ograve; Zope 3 essere ancora considerato un valido prodotto per lo sviluppo di applicazioni web? Secondo me si, soprattutto perch&eacute; parliamo di un framework maturo, stabile, e che oggi fornisce decine di componenti per le pi&ugrave; disparate necessit&agrave; (gestione form, sessioni, database, autenticazione, permessi, workflow, AJAX, REST, i18n, indicizazzione e ricerca, cache, testing) che altri framework non possono neanche lontanamente pensare di fornire. Come sfruttare al meglio tutto ci&ograve;?</p>
<p><a href="http://grok.zope.org/">Grok</a> &egrave; il prodotto della comunit&agrave; Zope nato per ridurre sensibilmente il ciclo di sviluppo di un&#8217;applicazione Zope 3. L&#8217;idea alla base di Grok &egrave; quella di riportare la piattaforma su un livello di programmazione agile e al tempo stesso intuitivo per il programmatore, senza sacrificare i dettami della <em>component architecture</em>. Grok introduce la nozione di direttive per indicare al framework quali caratteristiche una determinata componente deve avere: quella direttiva sar&agrave; espansa in istruzioni ZCML in maniera automatica senza che il programmatore deve impelagarsi in aspetti di configurazione delle componenti. <br />
Dopo anni di sviluppo Zope 2/3 devo dire che Grok &egrave; un prodotto molto eccitante. Si riesce veramente a sfruttare al pieno la piattaforma senza doversi sobbarcare molti degli aspetti che l&#8217;hanno resa ostica. Tanto per far capire, vi faccio un esempio rapido di una semplice applicazione Grok.<br />
&nbsp;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> grok
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> App<span style="color: black;">&#40;</span>grok.<span style="color: black;">Container</span>, grok.<span style="color: black;">Application</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Index<span style="color: black;">&#40;</span>grok.<span style="color: black;">View</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> reder<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #66cc66;">&amp;</span>quot<span style="color: #66cc66;">;&lt;</span>h1<span style="color: #66cc66;">&gt;</span>Hello World<span style="color: #66cc66;">!&lt;</span>/h1<span style="color: #66cc66;">&gt;&amp;</span>quot<span style="color: #66cc66;">;</span></pre></td></tr></table></div>

<p>Il codice per molti sar&agrave; estremamente chiaro: si crea la classe che rappresenta l&#8217;intera applicazione (<span style="font-family: Courier New;">App</span>) che sar&agrave; automaticamente instanziata dal framework all&#8217;atto del caricamento, e la vista di default dell&#8217;applicazione (<span style="font-family: Courier New;">View</span>) che restituisce la stringa HTML &quot;<span style="font-family: Courier New;">&lt;h1&gt;Hello World!&lt;/h1&gt;</span>&quot;.</p>
<p>Ovviamente questo frammento di codice non &egrave; sufficiente a far capire n&eacute; quanto Grok possa semplificare la vita n&eacute; quanto Zope 3 sia completo e potente, ma chi conosce un po&#8217; di Zope non pu&ograve; non ammettere che siamo alla presenza di un sensibile passo in avanti.</p>
<p>Continuer&ograve; a presentare Grok sul mio blog, con tutorial pi&ugrave; completi e casi concreti, perch&eacute; credo seriamente che Grok sia il futuro della piattaforma Zope 3, o se non altro contribuir&agrave; al suo sviluppo. Nel frattempo non posso fare altri che rimandarvi al <a href="http://www.pycon.it/pycon3/programma/">PyCon Tre</a>, nel quale terr&ograve; un talk introduttivo su Grok con Francesco Merlo. Ci vediamo a Firenze!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.carminenoviello.com/2009/05/02/dalla-preistoria-arriva-grok-per-il-futuro-di-zope-3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

