quixote(parte2)

Il file uno.ptl :

# -*- coding: UTF-8 -*- # forziamo la codifica unicode
from quixote import *
from quixote.directory import Directory , Resolving
from due import dirc2 # Qui importiamo un altra istanza di Directory
from quixote.html import * # Qui import htmltext ed altre utilita



class dirc(Resolving,Directory):

_q_exports = [ " ", "header" , "css", "footer", " res", "res2", "due"]

“””

Questa classe eredita da Directory e Resolving.Un istanza di questa classe è

viene passata come argomento al Publisher ritornato dalla funzione handler

(che interfaccia l apllicazione al server) create_publisher() appunto.

Come si vede il primo attributo _q_exports [] contiene una lista di stringhe.

Queste stringhe rappresentano la mappatura tra url e metodi della classe.

In pratica ognuna di queste stringhe aggiunta alla base url dell applicazione

richiama il corrispondente metodo della classe che ha lo stesso nome.

La stringa vuota (” “) non obbligatoria,corrisponde al metodo _q_index

che abbiamo subito sotto.In un file di template un metodo o funzione

deve avere la direttiva [html] (nel caso di output html). [plain] (nel caso

si necessiti di output formato testo.

Il metodo di template [html] consiste in un elenco di espressioni python

di cui quixote ne fa automaticamente

l’ escaping e l’ output.Oltre che formattare stringhe per l output html.

possiamo chiamare metodi della classe ,attributi,funzioni.In sintesi si tratta di una vera e propria

funzione python.D’ altronde i file di Template come questo ,con estensione .ptl

possiamo importarne i nomi nel namespace che vogliamo come un comune

modulo python.Tra le poche differenze tra i moduli python ed i template Quixote,

siccome nelle funzioni qualsiasi espressione va in output con escaping autom.

senza necessita di ritornare un valore.Per questo nei moduli di template non

si possono usare le __doc__ string come attributo modulo,dato che anch esse

vanno in output automatico.

Come possiamo vedere Dirc() eredita anche da Resolving , obbligatorio nel caso

si voglia usare il metodo _q_resolve() che spiegheremo sotto.

“””

def _q_index [html] (self):

self.header()

“””

Dopo la chiamata al metodo header definito sotto.Abbiamo le

espressioni del metodo di template _q_index [html] (self).

vediamo che non c’ e bisogno di scrivere dei valori di ritorno per

avere aotput di dati html.basta scrivere i dati stessi o formattarli.

i primi 2 valori sono i parametri del costruttore di Dirc(),che

essendo valori che vengono da fuori la funzione vengono cosi

automaticamente escaping.

L altra variabile var_1 Essendo locale alla funzione ,definita esattamente li.

Di quest ultima non viene fatto escaping¹.

“””

‘<h5> parametro name -> %s </h5>’ % self.attr1

‘<h5>’

self.attr2

‘</h5>’

var_1 = ‘<strong>variabile locale</strong>’

‘<p> questa senza escaping %s </p><br />’ % var_1

‘<a href=due>istanza sottodirectory</a>’

self.footer()

“””

Questo sotto è il costruttore.Quando in mio.py instanziamo la classe dirc ,esso prende come argomento 2 stringhe.Il costruttore non

è obbligatorio noi ce ne serviamo per esercizi sull escaping dei cartteri nei template html.

Attraverso le 2 variabili self.attr1 e self.attr2

“””

def __init__(self,name,cname):

self.attr1 = name

self.attr2 = cname

# l url due richiama una nuova istanza di classe Directory,In pratica sarebbe la sottodirectory di livello 1

# mentre dirc() di uno.ptl crea e mappa per la root dir.Se ad esempio la root dir o base url e http://www.home.it/

#Anzi in locale metteremo (http://localhost/ ) uno.dirc() mappa le stringhe agli urls di 1 livello nell

#albero directory. E definisce tutti i suoi attributi-urls (http://localhost/fun , http://localhost/fun1 ecc. ecc.)

#Chiamando l’ attributo mappato in _q_exports [ 'due'] , (http://localhost/due)ad esempio con un link

#come nel _q_index() sopra .Verra istanziata dirc2() da due.ptl ,essa si aggancera alla root dir dell

#albero di directory e cosi anche al “base url” http://localhost,e cosi tutti i metodi o attributi mappati nel suo

# _q_exports [ ] si agganceranno ad una nuova base non piu quella di root ma la sottodir “due”

# (http://localhost/due/nomemetodo , http://localhost/due/nomeattributo)

due = dirc2()

def header (self, titolo):

“””

Questo metodo (chiamato sopra in _q_imdex) si occupa dell output degli header

della pagina.Per semplificare non mettiamo tutti i tag necessari per un header

di produzione,ma solo alcuni per capirne il funzionamento.Intanto il metodo

riceve un argomento, il titol della pagina,che viene formattato come stringa.

Questo metodo a differenza di _q_index non ha il parametro [html] alla

definizione,questo significa che non fa escaping automatico come nel

template PTl con direttiva [html] .Quindi per fare escaping di tag (ammesso sempre

che sia necessario,questi sono esempi ,ma la necessita si avrebbe solo nel caso di imput

utente da ripulire ,oppure valori di ritorno es espressioni,e variabili globali che

potrebbero essere state modificate.Al contrario variabile locali ,create esplicitamente

all interno di una funzione,non necessitano di escaping automatico.

Quando non abbiamo escaping automatico ,come in questo metodo (header)

possiamo comunque usare delle funzioni di utilita che Quixote ci mette a disposizione.

Come quelle che si occupano appunto dell HTML nel modulo ‘ quixote.html’.


“””

return htmltext(“””

<!DOCTYPE html PUBLIC ‘-//W3C//DTD XHTML 1.0 Transitional//EN’

‘http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd’>


<html xmlns=’http://www.w3.org/1999/xhtml’>

<head>
<title>%s</title>
<link rel=’stylesheet’ href=’css’ type=’text/css’ />

</head>

<body>

“””) % titolo


def _q_lookup(self, component):

return”””
<p>L url %s non esiste !</br>

Molto probabilmente non è presente la stringa</br>

in _q_exports </p>

“”” % component



def _q_resolve [html] (self, component):

if component == ‘res':


“””
<h5>
template di _q_resolve ,che serve quando una stringa url è si presente in _q_export
<br />ma non abbiamo nessun metodo o attributo definito nella classe con quel nome.<br />
Quindi se l url aggiunto alla base del root directory è ‘res’
si attiva la condizione if<br />
per gli altri stringa-url si attiva la condizione else.(se presente in _q_exports[])<br />
questo metodo potrebbe essere superfluo ,dato che ci basterebbe definire i metodi per certi nomi<br />
Comunque possiam scegliere se definire un metodo-attributo qui oppure nel primo livello della classe<br />
come piu comune.<br />
FARE ATTENZIONE QUANDO SI CREA LA CLASSE dirc() <br />
ESSA EREDITA DA Directory E DA Resolving.<br />
Resolving SERVE SOLTANTO PER USARE LA FUNZIONE _q_resolve<br />
Nel caso avessimo tutti i metodi-attributi definiti nella classe<br />
potremmo anche ovviare di importare Resolving.<br />

IN CASO CONTRARIO SI PUO EREDITARE SOLO DA Directory

</h5>
“””


else:


“””
<h5>
questo per quando il component in _q_resolve non e ‘res'<br />

ma res2
[sempre però presente in _q_exports]<br />
altrimenti si attiverebbe l metodo _q_lookup
</h5>
“””

#Il metodo css definito sotto viene istanziato alla chiamata che si ha nella

#definizione del metodo header sopra. Questo modo di creare file dinamicamente si puo

#usare anche per altri tipi di file ,script ,immagini, ecc.

#Ci sono comunque anche dei modi per usare file staticamente,che forse spesso è piu

#opportuno.Vedremo nel proseguio.


def css [html] (self):

get_response().set_content_type(“text/css”)

‘p { border: thick solid green; padding: 2em; }’

‘h5 { background-color:#000000;color:#ffffff;}’
‘A:LINK{text-decoration : none;color: #333333;}’

‘A:VISITED{text-decoration : none;color: #333333;}’
‘A:HOVER{color: #CC0516;text-decoration : none;}’

#Il metodo footer chiude la pagina principale di questa demo.²

#Infatti mentre header() termina con l output del tag <body>

#corpo che poi sara definito da altri metodi.footer() invece

#finisce proprio con la chiusura dei tag fine pagina </body> </html>

#oltre a qualche eventuale informazione classica della base pagina.

#Differiscono poi dal fatto che mentre header() è un classico metodo di classe python

#footer() qui invece usiamo le direttive per il template PTL [html]

#con le note differenze in output delle stringhe.

def footer [html] (self):

‘<h5>questo testo sta alla base della pagina</h5></body></html>’

—————– fine file —————————————————————

1] Riguardo l escaping di Quixote ,e di come in genere tratta l ouput delle stringhe ,bisogba specificare

il suo funzionamento .Abbiamo detto che nei template [html] PTL viene fatto automaticamente l escaping dei

valori designati. In pratica essi vengono (in background) passati ad un istanza di htmltext ,che è una funzione

appartenente al modulo html di quixote.Bisogna fare attenzione , perchè se quei valori automaticamente escape,

vengono passati di nuovo alla funzione htmltext ,si ha il fenomeno dell “OVERQUOTING” (doppio escape)

In pratica i valori i cui caratteri pericolosi sono stati sostituiti con il loro corrispondente entita carattere

( < con &lt; > con &gt; & con 6amp;) ripassando a htmltext essi sono di nuovo eseguibili.

Alcuni suggeriscono di usare (nei template PTL [html]) la protezione htmltext.

Essa consiste nel prendere la variabile , passarla in un istanza con htmltext con a sx nell espressione di

formattazione : [var = htmltext('%s') % self.name ]. A questo punto la variabile var ,sia se la passiamo

per l output al template ordinariamente ,o attraverso una nuova istanza htmltext,il suo codice

non potra piu essere reso eseguibile.

Cosa che non succede se settiamo var cosi :

var = htmltext(self.name) con metodo secco

var = “%s” % htmltext(self.name) con hmltext a dx dell espressione formattazione stringa

In questi casi avremo sempre OVERQUOTING , con tutti gli eventuali rischi di codice malevolo.

Altra soluzione è passare la variabile da proteggere a str().In questo caso la stringa di formattazione va creata con

str() a dx (al contrario di htmltext):

var =”%s” % str(self.name) perche se facciamo :

var = str(self.name) oppure var= str(“%s”) % self.name avremo ancora codice eseguibile.

Comunque ritengo questo l aspetto peggiore di Quixote. e consiglio di usare sempre template di tipo [html]

e di non usare mai htmltext,oppure di ridurne al minimo l uso.

Usiamo htmltext solo nel caso di funzioni python classiche o template [plain].

2] Per esigenze didattiche abbiamo fatto largo uso di __doc__ string (quelle tra le triple virgolette doppie)

Inoltre abbiamo anche linne di commenti classici come quelli a cui si riferisce questo numero ² di legenda.

Siccome per i template PTL le doc string vengono date automaticamente in output ,senza

bisogbno di essere richiamate direttamente attraverso l attributo __doc__.

Consiglio di fare attenzione nel caso di copia del codice per esercitazione,dato che tutto potrebbe rendere

illegibili le pagine di output.Se meglio consiglio di eliminare i commenti.

Parte 3

Leave a Reply

Your email address will not be published.


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>