Modern Web Development
I Web Application Frameworks
Data: 12/12/2013
Docente:
Valerio Panzica La Manna
Politecnico di Milano
[email protected]
www.webmoderno.wordpress.com
© copyright CEFRIEL- Valerio Panzica La Manna -Milano-Italia- 2013_ Tutti i diritti riservati
PYTHON AND DJANGO
2
Introduzione
n 
n 
n 
n 
Django è un web application framework open-source che
utilizza il linguaggio Python.
Come Rails Django segue il paradigma MVC.
Caratteristiche principali:
–  Architettura a componenti:
•  Riutilizzabile
–  Prototipazione rapida
–  DRY
Molto utilizzato
–  Pinteresest
–  Instagram
–  Mozilla
3
© 2007 - CEFRIEL
Componenti Principali
n 
Model
–  Object-relational mapper tra database relazionali e classi python
(data model)
n 
View
–  Web Templating Systems
–  Basato sul concetto di ereditarietà
n 
Controller
–  Delega le richieste sulla base di espressioni regolari
n 
Stand-alone web server
–  per sviluppo e testing
n 
n 
n 
Sistema di serializzazione e validazione dei form
Framework di caching
Built-in unit test framework
4
Applicazioni di default intergrate
n 
n 
Sistema di autenticazione
Sistema per l’interfaccia lato admin
–  Assente di default in Rails (ma integrabile tramite gem)
n 
n 
n 
Sistema per la gestione dei commenti
Generazione di sitemaps
Protezione dai tipici attacchi web
–  SQL Injection
–  Cross-site scripting
–  Password cracking
n 
Framework per la creazione di applicazioni GIS
5
Creare un progetto
django-admin.py startproject mysite
n 
Struttura del progetto creato
– 
– 
– 
– 
– 
– 
n 
manage.py Utility per gestire il progetto
mysite la vera e propria cartella di progetto
mysite/__init__.py file vuoto che identifica la cartella come package
mysite/settings.py per le configurazioni
mysite/urls.py per la specifica del dispatching
mysite/wsgi.py entry-point per web-servers compatibili con wsgi
(protocollo tra server e Python)
Lancio del server (porta del server opzionale)
python manage.py runserver 8000
6
setting.py (Database)
n 
Supporto built-in ai database:
– 
– 
– 
– 
n 
SQLLite (default)
PostGresSQL
MySQL
Oracle
Configurazione
–  ENGINE: nome del package per il binding
•  Es: django.backends.sqlite3
–  NAME: nome del database
•  Nel Caso di SQLLite path del file
7
settings.py (gestione delle app)
n 
n 
INSTALLED_APPS contiene il nome di tutte le applicazioni
Django da includere nel progetto.
Default
– 
– 
– 
– 
– 
– 
django.contrib.admin (pannello di amministrazione)
django.contrib.auth (sistema di autenticazione)
django.contrib.contenttypes (framework per la gestione dei tipi)
django.contrib.sessions (sessioni)
django.contrib.messages (framework per i messaggi)
django.contrib.staticfiles (gestione file statici: immagini, css..)
8
syncdb
n 
n 
n 
n 
python manage.py syncdb
Il comando verifica il contenuto di INSTALLED_APPS e
crea tutte le tabelle necessarie al lancio delle applicazioni.
Es: Tra le applicazioni di default l’applicazione di auth
richiede la creazione di tabelle.
Lo stesso comando viene utilizzato per la generazione
delle tabelle relative al modello del progetto.
9
Creiamo un app polls
n 
n 
n 
n 
n 
Django distingue progetti da app.
Una app è un modulo con funzionalità specifiche.
Un progetto è composto da diverse app.
La stessa app può essere utilizzata in più progetti
Procedura:
–  la app viene creata all’esterno di mysite (allo stesso livello di
manage.py)
–  questo ci permette di importarla tra le INSTALLED_APP e utilizzarla
in mysite.
n 
Comando: python manage.py startapp polls
10
Struttura di una app
n 
polls/
– 
– 
– 
– 
__init__.py
admin.py
models.py file che contiene tutte le classi dei modelli
views.py
11
models.py
from django.db import models
class Poll(models.Model): #ogni classe eredita da models.Model
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
12
Aggiungiamo polls in
mysite/settings.py
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
)
n 
n 
creiamo le tabelle
python manage.py syncdb
13
Console Interattiva
n 
n 
E’ possibile testare i propri modelli e le API di Django
tramite shell interattiva.
python manage.py shell
>>> from polls.models import Poll,
>>> Poll.objects.all()
[]
>>> from django.utils import timezone
>>> p = Poll(question="What's new?", pub_date=timezone.now())
>>> p.save()
>>> p.id
1
>>> p.question
"What's new?”
>>> p.question = "What's up?"
>>> p.save()
>>> Poll.objects.all()
[<Poll: Poll object>]
14
Specificare metodi nel modello
n 
Il modello non contiene solo i campi dei dati, ma anche
operazioni su esse.
import datetime
from django.utils import timezone
# ...
class Poll(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() datetime.timedelta(days=1)
15
Pannello di Amministrazione
n 
n 
n 
n 
Il pannello di admin (l’app associata) è presente di default
nel progetto.
Raggiungibile da browser all’url ../admin/
Permette la gestione dei modelli
Configurare admin per includere polls
–  Modifichiamo il file polls/admin.py
from django.contrib import admin
from polls.models import Poll
#personalizzazione di admin
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None,
{'fields': ['question']}),
('Date information', {'fields': ['pub_date']}),
]
admin.site.register(Poll, PollAdmin)
16
Views
n 
1. 
2. 
Procedura per la creazione di una view:
All’interno di views.py dell’app definiamo i metodi che
specificano cosa visualizzare.
Associamo un url al metodo
1.  Creiamo un nuovo file polls/urls.py
2.  Specifichiamo il pattern dell’url e il suo mapping con il metodo in
views.py
3. 
Nel progetto importiamo i mapping specificati per l’app
17
Primo esempio di views
n 
All’interno di views.py dell’app definiamo i metodi che
specificano cosa visualizzare.
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the poll
index.")
n 
n 
ogni metodo ha come parametro la richiesta
ritorna una HttpResponse
18
Primo esempio di views
n 
Associamo un url al metodo
–  Creiamo un nuovo file polls/urls.py
–  Specifichiamo il mapping tra url e metodo
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index')
n 
) ogni metodo ha come parametro la richiesta
19
Primo esempio di views
n 
Nel progetto (mysite/urls.py) importiamo i mapping
specificati per l’app
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls')),
url(r'^admin/', include(admin.site.urls)),
)
20
la funzione url() parametri
n 
regex
– 
– 
– 
– 
n 
espressione regolare che definisce il pattern dell’url da mappare.
Il matching viene fatto in sequenza sui file urls.py
Il primo pattern è quello associato.
Il pattern è sull’URL non sul metodo HTTP
view
–  nome della funzione della view da associare
n 
name
–  associa un nome all’URL
21
Parametri nella richiesta (views.py)
def detail(request, poll_id):
return HttpResponse("You're looking at poll %s." %
poll_id)
def results(request, poll_id):
return HttpResponse("You're looking at the results of
poll %s." % poll_id)
def vote(request, poll_id):
return HttpResponse("You're voting on poll %s." %
poll_id)
22
specifica parametri nel pattern
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
# ex: /polls/
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<poll_id>\d+)/results/$', views.results,
name='results'),
# ex: /polls/5/vote/
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
23
Template
n 
n 
E’ possibile associare template alle view
In Django si preferisce separare i template per ogni app
–  Diversamente da Rails dove sono tutti insieme nella cartella view
n 
Es:polls/index.html
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
24
Rendering del template
n 
Modifichiamo views.py per visualizzare il template
from django.http import HttpResponse
from django.template import RequestContext, loader
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = RequestContext(request, {
'latest_poll_list': latest_poll_list,
})
return HttpResponse(template.render(context))
n 
context associa un oggetto a un elemento del template.
25
TESTING IN DJANGO
26
Testing in Django
n 
Potremmo testare la nostra applicazione tramite la shell
–  Verificare che i modelli e le validazioni sui campi vanno a buon fine.
–  Eseguire i metodi dei modelli e delle view.
n 
Questo non è sufficiente
–  Nel contesto di uno sviluppo di applicazioni complesse molti
componenti (classi, modelli, views) interagiscono tra di loro.
–  In un linguaggio come Python non siamo supportati dal compilatore
–  E se il codice evolve? Nuovi requisiti e funzionalità devono essere
aggiunte?
n 
E’ quindi necessario un approccio al testing sistematico e
automatico.
–  Sistematico: TDD
–  Automatico: framework di testing
27
© 2007 - CEFRIEL
Perché un testing sistematico
n 
Riduce i tempi di sviluppo.
–  Un cambiamento del codice richiede allo sviluppatore di verificare
manualmente che tutto funzioni come previsto.
–  Questo procedimento si ripete ad ogni cambiamento.
n 
I test non solo identifica gli errori: li previene.
–  L’obiettivo di verificare manualmente che “tutto funzioni” non è
preciso.
–  Scrivendo i tests si obbliga lo sviluppatore a pensare in maniera
precisa quale è il comportamento atteso.
n 
Migliora lo sviluppo in team
–  La modifica del codice da parte di un altro membro del team può far
fallire dei test.
–  I test documentano l’uso corretto del codice scritto.
28
Esempio
import datetime
from django.utils import timezone
# ...
class Poll(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() datetime.timedelta(days=1)
n 
Il metodo ritorna true se la data di pubblicazione è
successiva a ieri.
29
Esempio
import datetime
from django.utils import timezone
# ...
class Poll(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() datetime.timedelta(days=1)
n 
n 
Il metodo ritorna true se la data di pubblicazione è
successiva a ieri.
Ma anche se pub_date viene settato ad una data futura
30
Creazione di un test
n 
I test sono inseriti in tests.py dell’app
import datetime
from django.utils import timezone
from django.test import TestCase
from polls.models import Poll
class PollMethodTests(TestCase):
def test_was_published_recently_with_future_poll(self):
future_poll = Poll(pub_date=timezone.now() +
datetime.timedelta(days=30))
self.assertEqual(future_poll.was_published_recently(), False)
n 
Un test è una classe che eredita da TestCase
31
Esecuzione dei test
n 
Comando: python manage.py test polls
n 
Cerca tutti i test all’interno di tests.py in polls
Se trova una classe che eredita da TestCase
Esegue tutti i metodi che iniziano con la parola test
n 
Fix del bug:
n 
n 
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date < now
32
Testare La View
n 
La parte critica e specifica delle applicazioni web è
l’interazione con gli utenti.
–  Un bug in questa interazione è direttamente visibile all’utente.
n 
n 
n 
Il testing unitario dei modelli non è sufficiente.
Django offre un insieme di tool per il testing di questa
interazione.
Test Client: simula il comportamento dell’utente che
interagische con la view.
33
Test client da shell
>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()
n 
n 
setup_test_environment() permette di analizzare attributi
specifici della view (es. gli attributi di context)
non crea un nuovo database
–  lavora sul database reale.
>>> from django.test.client import Client
>>> client = Client()
n  crea l’oggetto Client
>>> from django.test.client import Client
>>> client = Client()
>>> response = client.get('/')
>>> response.status_code
404
34
Test client da shell (2)
>>> from django.core.urlresolvers import reverse
>>> response = client.get(reverse('polls:index'))
>>> response.status_code
200
>>> response.content
'\n\n\n <p>No polls are available.</p>\n\n’
>>> from polls.models import Poll
>>> from django.utils import timezone
>>> p = Poll(question="Who is your favorite Beatle?",
pub_date=timezone.now())
>>> p.save()
>>> response = client.get('/polls/')
>>> response.content
'\n\n\n <ul>\n \n
<li><a href="/polls/1/">Who is your favorite
Beatle?</a></li>\n \n </ul>\n\n'
>>> response.context['latest_poll_list']
[<Poll: Who is your favorite Beatle?>]
35
Testing della view
n 
n 
in tests.py di polls
creiamo un metodo create_poll per la creazione di nuovi
oggetti poll
def create_poll(question, days):
return Poll.objects.create(question=question,
pub_date=timezone.now() + datetime.timedelta(days=days))
n 
questo metodo non viene eseguito come test perché il
nome del metodo non inizia con test
36
PollViewTests
class PollViewTests(TestCase):
def test_index_view_with_no_polls(self):
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_poll_list'], [])
def test_index_view_with_a_past_poll(self):
create_poll(question="Past poll.", days=-30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_poll_list'],
['<Poll: Past poll.>']
)
37
Altri Tipologie di Test
n 
n 
Django permette di integrare altri componenti utili per il
testing.
coverage.py
–  copertura: misura della porzione di codice coperta dai test
–  Identificazione di Dead Code (codice mai utilizzato)
n 
Selenium
–  framework di testing “in-browser”
–  testa il modo in cui la pagina html è effettivamente renderizzata sul
browser.
–  permette anche il testing del javascript associato alla pagina
38
PANORAMICA FRAMEWORK PHP
39
Introduzione
n 
n 
n 
n 
n 
n 
n 
n 
Ruby e Python hanno un framework di riferimento per lo
sviluppo di applicazioni web
Lo stesso non si può dire per PHP.
PHP nasce infatti come linguaggio per il web.
Tra i frameworks più popolari:
Zend
Symfony
CakePhP
CodeIgniter (?)
40
© 2007 - CEFRIEL
ZEND
41
Zend 2
n 
n 
n 
Zend Framework 2 è un framework open-source
object-oriented
si basa e sfrutta le caratteristiche di PHP 5.3
–  namespaces
•  per evitare collisioni tra codice proprio e di terze parti
•  introdurre alias per migliorare la leggibilità
–  late static binding
–  closures
n 
caratteristiche
– 
– 
– 
– 
MVC
rendering di form HTML5
validazione e filtri
autenticazione e autorizzazione
42
© 2007 - CEFRIEL
Moduli
n 
n 
n 
Zend usa un sistema modulare per l’organizzazione
dell’applicazione.
Il modulo Application contiene i controllers a livello root.
Struttura di un modulo (definisce i namespaces)
/module
/Album
/config
/src
/Album
/Controller
/Form
/Model
/view
/album
/album
43
ModuleManager
n 
n 
n 
ModuleManager ha il compito di caricare e configurare un
modulo.
Cerca il Module.php nella directory root del modulo
(module/Album)
All’interno del file cerca la classe con Album\Module
–  Album è il namespace e deve essere uguale al nome della cartella
–  Module il nome della classe
44
Module.php
namespace Album;
class Module
{
public function getAutoloaderConfig() // chiamata dal ModuleManager
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php', // quali classi trovare
),
'Zend\Loader\StandardAutoloader' => array( // e dove
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getConfig() //chiamata dal ModuleManager
{
//specifica dove sono I controller e gli script della view
return include __DIR__ . '/config/module.config.php';
}}
45
Aggiungere il modulo all’applicazione
n 
n 
Nel file di configurazione dell’applicazione specifichiamo
quali moduli caricare.
config/application/config.php
return array(
'modules' => array(
'Application',
'Album',
),
//….
);
// <-- Add this line
46
Routing
n 
n 
n 
n 
n 
Zend utilizza il paradigma URL ->Page -> Controller ->
action per la definizione del routing.
Ogni pagina è associata ad una action
Tante action sono raggruppate in controller
Tanti controller sono raggruppati in moduli
Pagina
Controller
Azione
Home
AlbumController
index
Nuovo album
AlbumController
add
Modifica album
AlbumController
edit
Rimuovi album
AlbumController
delete
Adesso dobbiamo definire gli URL
47
Routing
n 
n 
n 
n 
n 
Zend utilizza il paradigma URL ->Page -> Controller ->
action per la definizione del routing.
Ogni pagina è associata ad una action
Tante action sono raggruppate in controller
Tanti controller sono raggruppati in moduli
URL
Pagina
Controller
Azione
/album
Home
AlbumController
index
/album/add
Nuovo album
AlbumController
add
/album/edit/2
Modifica album
AlbumController
edit
album/delete/4
Rimuovi album
AlbumController
delete
Adesso vediamo come si specifca il routing.
48
Routing
n 
module.config.php di Album
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
49
Controller: Convenzioni
n 
Il Controller è una classe di nome {NomeDelController}
Controller
–  Es: AlbumController
n 
n 
Deve iniziare con lettera maiuscola
Il nome del file deve essere come quello della classe
–  Es: AlbumController.php
n 
E deve risiedere nella cartella Controller del modulo
–  Es: module/Album/src/Album/Controller
n 
n 
La classe controller deve avere un metodo pubblico per
ogni action
Il nome del metodo deve essere {nomeAction}Action
–  Es: indexAction
50
Controller
namespace Album\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class AlbumController extends AbstractActionController
{
public function indexAction()
{
}
public function addAction()
{
}
// …
}
51
Model
n 
n 
n 
1. 
Zend non fornisce di default un componenente Zend\Model
Molti componenti però possono essere integrati a secondo
delle esigenze.
Due Approcci:
Un approccio è avere diverse classi che rappresentano le
entità del modello.
–  Utilizzare un mapping tra gli oggetti e le entità nel DB.
2. 
Utilizzare un ORM esterno
– 
– 
Doctrine
Propel
52
Model
n 
module/Album/src/Album/Model/Album.php
namespace Album\Model;
class Album
{
public $id;
public $artist;
public $title;
// copia i dati da array ai campi della classe
public function exchangeArray($data)
{
$this->id = (!empty($data['id'])) ? $data['id'] : null;
$this->artist = (!empty($data['artist'])) ? $data['artist'] : null;
$this->title = (!empty($data['title'])) ? $data['title'] : null;
}
}
53
Mapping del modello con il DB
namespace Album\Model;
use Zend\Db\TableGateway\TableGateway;
class AlbumTable
{
protected $tableGateway;
public function saveAlbum(Album $album)
{
$data = array(
'artist' => $album->artist,
'title' => $album->title,
);
$id = (int) $album->id;
if ($id == 0) {
$this->tableGateway->insert($data);
} else {
if ($this->getAlbum($id)) {
$this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('Album id does not exist');
}
} }
54
Aggiorniamo il controller
n 
n 
Per visualizzare i dati nella view ritorniamo un ViewModel
Questo viene automaticamente passato allo script della
view
// module/Album/src/Album/Controller/AlbumController.php:
// ...
public function indexAction()
{
return new ViewModel(array(
'albums' => $this->getAlbumTable()->fetchAll(),
));
}
// ...
55
View
<table
class="table">
n  index.phtml
<tr>
<th>Title</th>
<th>Artist</th>
<th>&nbsp;</th>
</tr>
<?php foreach ($albums as $album) : ?>
<tr>
<td><?php echo $this->escapeHtml($album->title);?></td>
<td><?php echo $this->escapeHtml($album->artist);?></td>
<td>
<a href="<?php echo $this->url('album',
array('action'=>'edit', 'id' => $album->id));?>">Edit</a>
<a href="<?php echo $this->url('album',
array('action'=>'delete', 'id' => $album->id));?>">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</table>
56
SYMFONY
57
Symfony
n 
n 
Framework PHP largamente ispirato da altri Frameorks
come Rails, Django e Spring
A differenza di Zend usaun ORM
–  Propel
–  Doctrine
n 
n 
Testing con PHPUnit (come Zend)
Utilizzo
–  Delicious
–  DailyMotion
–  Yahoo! Bookmarks
58
© 2007 - CEFRIEL
Front Controller e Routing
n 
n 
n 
n 
Anche Symfony come Spring utilizza il front controller
pattern per il dispatching delle richieste.
E’ implementato in app_dev.php
Symfony utilizza YML come linguaggio per definire il
routing.
app/config/routing.yml
_welcome:
path: /
defaults: { _controller: AcmeDemoBundle:Welcome:index }
_demo:
resource: "@AcmeDemoBundle/Controller/DemoController.php"
type: annotation
prefix: /demo
59
Controllers
n 
n 
n 
I Controller in Symfony prendono in ingresso richieste
HTTP e ritornano HTTPResponse (come in Django)
In PHP vengono utilizzate variabili globali e funzioni
($_GET o $header())
Symfony invece fornisce due oggetti Request e Response
use Symfony\Component\HttpFoundation\Response;
$name = $request->query->get('name');
return new Response('Hello '.$name, Response::HTTP_OK, array('ContentType' => 'text/plain'));
60
Controllers e render
n 
n 
n 
Symfony seleziona il contoller sulla base del valore
_controller definito in routing.yml
Es: AcmeDemoBundle:Welcome:index
dove Welcome è il nome del controller e index è l’action
// src/Acme/DemoBundle/Controller/WelcomeController.php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class WelcomeController extends Controller
{
public function indexAction()
{
return $this->render('AcmeDemoBundle:Welcome:index.html.twig');
}
}
61
Rounting e annotazioni
n 
n 
Il routing non solo può essere definito in YML
Ma anche in XML, PHP o tramite annotazioni
_demo:
resource: "@AcmeDemoBundle/Controller/DemoController.php"
type: annotation
prefix: /demo
class DemoController extends Controller
{
/**
* @Route("/hello/{name}", name="_demo_hello")
* @Template()
*/
public function helloAction($name)
{
return array('name' => $name);
}
62
Template
n 
n 
Il controller effettua il render di template Twig
Twig è l’engine di deafult ma può essere utilizzato PHP.
{% extends "AcmeDemoBundle::layout.html.twig" %}
{% block title "Hello " ~ name %}
{% block content %}
<h1>Hello {{ name }}!</h1>
{% endblock %}
63
Twig
n 
File di testo che possono generare diversi tipi di contenuto
–  HTML,XML, CSV, LaTex,…
n 
Due tipi di delimitatori (come ERB in Rails)
–  {{ … }} Stampa la variabile o il risultato di un’espressione
–  {% … %} non ritorna (utile per i controlli logici, cicli …)
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
64
Controller e formati
n 
n 
n 
Lo stesso controller puà essere utilizzato per renderizzare
divesi formati (XML e HTML)
A secondo del formato specificato viene chiamato il
template associato
Esempio
–  XML -> hello.xml.twig
–  HTML -> hello.html.twig
n 
n 
Il formato può essere specificato nell’annotazione.
Route non ambigua tramite il placeholder {format}
/**
* @Route("/hello/{name}.{_format}", defaults={"_format"="html"},
requirements={"_format"="html|xml|json"}, name="_demo_hello")
* @Template()
*/
public function helloAction($name)
{ /…
65
Generazione di URL
n 
Redirect: redireziona l’utente ad un altro URL
return $this->redirect($this->generateUrl('_demo_hello', array('name' =>
'Lucas')));
n 
il metodo generateUrl prende in ingresso il nome della
route e un array di parametri.
$response = $this->forward('AcmeDemoBundle:Hello:fancy', array('name'
=> $name, 'color' => 'green'));
n 
Forward: inoltra la richiesta ad un’altra action
66
Caching
n 
E’ possibile configurare la caching per specifiche richieste.
La cache può essere configurata dalle annotazioni.
n 
Esempio: cache di un giorno
n 
/**
* @Route("/hello/{name}", name="_demo_hello")
* @Template()
* @Cache(maxage="86400")
*/
public function helloAction($name)
{
return array('name' => $name);
}
67
JAVASCRIPT
68
Introduzione
n 
n 
n 
n 
n 
JavaScript è un linguaggio molto diffuso per il front-end del
web
Linguaggio interpretato
Object based
A tipizzazione dinamica
Estensibile con moltissime librerie
69
© 2007 - CEFRIEL
<script>
n 
con il tag script è possibile includere codice javascript
direttamente nella pagina
<script language="javascript”>
<!-- Let old browsers ignore script function isPositiveNum(s) {
return (parseInt(s) > 0) }
// End of ignored area
</script>
n 
Il browser ignora gli script e interpreta il codice all’interno.
70
Variabili
n 
Le variabili possono contener
–  tipi predefiniti / oggetti/funzioni
n 
Tipi predefiniti
– 
– 
– 
– 
– 
n 
number
string
boolean
null
undefined
Tipizzazione dinamica
–  var answer = 42
–  answer = “Grazie a tutti”
n 
Tipizzazione debole
–  tipi di dato convertiti automaticamente
–  y = 42 + “is the answer” // ritorna “42 is the answer”
71
Scope
n 
Variabili possono essere locali o globali
–  variabli dichiarate senza var sono sempre globali
n 
Scope di variabili locali:
–  disponibili solo all’interno della funzione
n 
Scope di variabili globali:
–  disponibili in tutto il codice nel documento
n 
NB: Non esiste lo scope di blocco
–  variabli definite dentro un blocco sono visibili anche all’esterno
if (true) {
var x = 5;
}
console.log(x);
72
Funzioni
function function_name([par0] … [parN]) {
/*codice*/
}
n  parametri non inizializzati sono di valore “undefined”
function sum (add1, add2){
return add1 + add2;
}
var first = sum(3,4); // 7
var second = sum(3); // NaN
var third = sum(5,4,5); // 9
73
Oggetti
n 
Javascript utilizza:
–  Array per gestire collezioni indicizzate (indice intero)
–  Oggetti per rappresentare collezioni (chiave,valore)
<script type="text/javascript">
var a = {
name : 'mario',
surname : 'rossi',
getName : function(){return this.name;}
}
document.write(a.getName() + '<br/>');
a.surname = 'bianchi';
document.write(a.surname);
</script>
74
Oggetti
n 
Oggetti possono anche avere costruttori per la definizione
di valori
function LineItem (id, name, qty, price) {
this.productID = id;
this.productName = name;
this.qty = qty;
this.unitPrice = price;
this.total = price * qty;
}
cartLineItem = new Array();
cartLineItem[0] = new LineItem('ABC123', 'InkJet Colori', 1, 120);
cartLineItem[1] = new LineItem('RTT237', 'InkJet B/N', 2, 14);
cartLineItem[2] = new LineItem('LLJ947', 'LaserJet Colori', 2, 21);
75
Oggetti
n 
Con prototype è possibile emulare il concetto di classe in
OOP
function Employee () {
this.name = “”;
this.dept = “general”;
}
function Manager () {
this.reports =[];
}
Manager.prototype = new Employee;
76
Eventi
n 
n 
n 
n 
n 
n 
Documenti HTML possono generare eventi quando caricati
nel browser.
Eventi sono tipicamente associati/generati da elementi
HTML
Il codice di scripting client-side è scritto per definire
comportamenti lanciato da eventi.
Esempio
Un comportamento associato al caricamento della pagina
può essere definito da una funzione javascript associato
all’evento onLoad dell’elemento Body.
Altri tipi di eventi
–  unload
–  blur
–  focus
77
Event Handler
element.addEventListener
myButton.addEventListener(‘click’, function(){alert(‘ciao’);},
false);
n  attributo HTML
<button onclick = “alert(“ciao”)”>
n 
proprietà di un elemento DOM
myButton.onclick = function(event){alert(‘ciao’)}
n 
78
Eventi esempio
<script language="JavaScript">
function main() {
document.getElementById('idp').innerText = "New page content.";
}
</script>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<p onClick=“main();” id="idp">Default page content.</p>
</body>
</html>
79
ESERCIZI
80
AJAX
81
© 2007 - CEFRIEL
Ajax
n 
n 
n 
n 
n 
Gruppo di metodi per lo sviluppo di applicazioni client-side
interattive.
Prendono dati da un server in maniera asincrona
In background senza interferire con la visualizzazione e il
comportamento della pagina esistente.
L’utente non deve più aspettare che la pagina sia caricata
completamente ad ogni interazione.
Precauzioni sulla performance:
–  scambiare solo i dati necessari.
–  Durante la fase di caricamento del documento inviare meno dati
possibili
n 
Casi d’uso
– 
– 
– 
– 
Validazione realtime dell’input dell’utente
autocompletamenro
Caricamento dei dati on demand
UI complesse
82
Architettura
83
Tecnologie
n 
Funzioni Javascript
–  Invocata quando un evento è stato lanciato
n 
DOM
–  Permette di avere accesso e aggiornare elementi HTML tramite
javascript
n 
CSS
–  Modifica a runtime tramite javascript
n 
XMLHttpRequest
–  oggetto JavaScript che gestisce le interazioni con il server in
maniera asincrona
84
Ajax: Scenario
n 
n 
n 
n 
n 
L’utente interagisce con la pagina web che genera un
evento (es click di un bottone)
Una funzione Javascript cattura l’evento e crea un oggetto
XMLHttpRequest
Tramite quest’oggetto viene inviata una richiesta al server
La risposta del server è raccolta da una funzione di
callback che processa il risultato.
Aggiorna il DOM della pagina e mostra il risultato.
85
Ajax: scenario
86
Best practices
n 
Non usare Ajax per le funzionalità core
–  Javascript seppur mascherato è visibile dall’utente
n 
Sempre permettere all’utente di capire visualmente cosa
sta succedendo.
–  Monitor di attività (progress, spinner)
n 
n 
Definire un timeout di connessione
Dare sempre all’utente la possibilità di fare abort dell’attività
87
JQUERY
88
Introduzione
n 
n 
n 
Jquery è un framework Javascript, cross-browser per
applicazioni web.
Si pone l’obiettivo di semplificare lo sviluppo lato client di
pagine HTML.
Tantissime operazioni con poche linee di codice.
–  Ottenere l’altezza di un elemento
–  Far scomparire un elemento con dissolvenza
n 
n 
La gestione degli eventi è completamente standardizzata
Offre funzioni per Ajax molto utili per l’invio di dati.
89
© 2007 - CEFRIEL
Core
n 
Il Core di Jquery fornisce:
–  Costruttori per l’utilizzo della libreria
•  ottenere elementi tramite selettori
•  ottenere elementi tramite parametro
•  creazione di nuovi elementi
–  metodi e proprietà per accedere agli elementi contenuti in oggetto
jQuery
•  numero degli elementi
•  iterazione sugli elementi
•  conoscere il selettore utilizzato
–  metodi per creare liste e code
–  metodi per l’estensione del framework
–  animazioni
90
Selettori
n 
n 
I selettori sono strumenti utilizzati per ottenere o puntare
elementi HTML della pagina
Utilizzano la stessa sintassi di CSS
–  in base all’id
•  #idvalue
–  in base alla classe
•  .classname
–  gerarchie
•  ancestor, sibling
–  in base ad attributi o contenuti
•  :hidden, [type =“text”]
91
Attributi
n 
n 
n 
n 
jQuery fornisce una API compatibile con tutti i browser per
l’accesso e modifica degli attributi
attr() Attributi generici
hasClass(), addClass(), removeClass() classi
metodi per il contenuto
–  html()
–  text()
–  val()
92
Manipolazione e Navigazione del DOM
n 
Navigazione
–  Metodi per risalire a elementi padre
–  nodi fogli
–  elementi successivi
n 
Manipolazione
– 
– 
– 
– 
aggiungere/rimuovere nuovi elementi alla pagina
sostituire elementi
circondare elementi con nuovo contenuto
eliminare tutti gli elementi contenuti in un nodo
93
CSS, Eventi ed Effetti
n 
Controllo dello stile degli elementi
–  Cambiare, rimuovere o aggiungere proprietà grafiche
–  Ottenere e sostituire proprietà difficili da manipolare (dimensioni,
scroll…)
n 
Eventi
–  Il framework riconosce oggetti di tipo event e modifica le proprietà
rendendoli uniformi
–  Gestione e propagazione semplificata
n 
Effetti
–  Servono a manipolare la visibilità di elementi
–  fading, sliding…
94
Ajax
n 
1. 
2. 
Sono fornite tre tipologie di funzioni che semplificano la
gestione delle chiamate asincrone.
Caricare contenuti dinamicamente
Esecuzione richieste
1.  Metodo GET
2.  Metodo POST
3. 
Interazione con javascript
1.  Funzione per caricare un oggetto JSON
2.  caricare un file javascript remoto ed eseguirlo
95
Oggetto jQuery
n 
n 
L’oggetto principale, di nome jQuery è tipicamente utilizzato
con l’alias $
Selettori
–  Ritorna tutte le immagini di classe a e/o b
–  $(“img.a, img.b”);
n 
Concatenazione del codice
$(“a”).css({color : “red”, width : “150px”})
.bind( "click", myFunctionPointer ).show( "1000" );
96
Inizializzazione
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Demo</title>
</head>
<body>
<a href="http://jquery.com/">jQuery</a>
<script src="jquery.js"></script>
<script>
// Your code goes here.
</script>
</body>
</html>
97
document ready
n 
n 
n 
Per permettere che il codice venga eseguito quando il
browser finisce di caricare la pagina.
Abbiamo visto la versione JavaScript onload
Problemi:
–  Il codice non parte finché tutte le immagini sono state caricate
–  Inclusi i banner pubblicitari
n 
jQuery
$( document ).ready(function() {
// Your code here.
});
98
Esempio
$( document ).ready(function() {
$( "a" ).click(function( event ) {
alert( "Thanks for visiting!" );
});
});
cliccando su un link viene mostrato un popup e visualizzata
la pagina linkata
n  possiamo prevenire l’azione di default
$( document ).ready(function() {
$( "a" ).click(function( event ) {
event.preventDefault();
alert( ”Link no longer working!" );
});
});
n 
99
Aggiungere e Rimuovere Classi HTML
n 
n 
n 
n 
n 
Metodo addClass
$(“a”).addClass(“test”)
aggiunge la classe test a tutti gli elementi a (link)
Metodo remove Class
$(“a”).removeClass(“test”)
100
Effetti
n 
n 
jQuery offre degli effetti e delle animazioni agli elementi
Esempio: hide
$( "a" ).click(function( event ) {
event.preventDefault();
$( this ).hide( "slow" );
});
101
CallBacks e Funzioni
n 
n 
n 
n 
n 
JavaScript permette di passare funzioni come parametri da
eseguire più in avanti nel tempo.
La callback è una funzione passata come parametro ad
un’altra funzione.
E’ eseguita dopo che la funzione padre ha terminato.
Nel frattempo il browser può eseguire altre funzioni e altro.
Senza Argomenti
$.get( "myhtmlpage.html", myCallBack );
n 
Con parametri
$.get( "myhtmlpage.html", function() {
myCallBack( param1, param2 );
});
102
Ajax e JQuery
n 
n 
n 
n 
Ci sono molti modi per utilizzare AJAX con jQuery.
Uno dei più semplici per caricare dati asincronamente è il
metodo load
Selezione un elemento nel quale inserire i dati caricati ed
esegui load.
Prende in ingresso l’url della risorsa da caricare.
103
Esempio
n 
Abbiamo il file content.html che contiene i dati da caricare
<div id="divContent">
<b>This is external content</b>
</div>
And there's more of it
n  Lo carichiamo nell’elemento divTestArea1
<div id="divTestArea1"></div>
<script type="text/javascript">
$(function()
{
$("#divTestArea1").load("content.html");
});
</script>
104
Load con selector
n 
n 
E’ possibile specificare un selettore come parametro della
load.
In questo modo possiamo caricare solo parte del
contenuto.
<div id="divTestArea2"></div>
<script type="text/javascript">
$(function()
{
$("#divTestArea2").load("content.html #divContent");
});
</script>
105
Load con callback
<div id="divTestArea3"></div>
<script type="text/javascript">
$(function()
{
$("#divTestArea3").load("no-content.html",
function(responseText, statusText, xhr)
{
if(statusText == "success")
alert("Successfully loaded the content!");
if(statusText == "error")
alert("An error occurred: " + xhr.status + " - " +
xhr.statusText);
});
});
</script>
106
Metodi get() e post()
n 
n 
I metodi get() e post() permettono di inviare facilmente
richieste HTTP e riceve la risposta indietro.
Metodo get() Versione con callback
<script type="text/javascript">
$(function()
{
$.get("content.html", function(data, textStatus)
{
alert("Done, with the following status: " +
textStatus + ". Here is the response: " + data);
});
});
</script>
107
Metodi get() e post()
n 
Metodo post() Versione con callback e parametri in
ingresso. La callback viene chamata solo in caso di
successo.
<script type="text/javascript">
$(function()
{
$.post("test_post.php",
{
name: "John Doe",
age: "42"
},
function(data, textStatus)
{
alert("Response from server: " + data);
});
});
</script>
108
Ajax
$.ajax({
url: "http://fiddle.jshell.net/favicon.png",
beforeSend: function( xhr ) {
xhr.overrideMimeType( "text/plain; charset=x-userdefined" );
}
})
.done(function( data ) {
if ( console && console.log ) {
console.log( "Sample of data:", data.slice( 0, 100 ) );
}
});
109
JQUERY UI
110
Introduzione
n 
jQuery UI è un insieme che raccoglie diversi elementi per
l’interfaccia grafica.
–  interazioni, effetti, widgets e temi.
n 
jQuery UI Demos
–  http://jqueryui.com/demos/
n 
1. 
Utilizzo
importare il framework
<link rel="stylesheet" href="css/themename/jquery-ui.custom.css" />
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.custom.min.js"></script>
2. 
3. 
HTML : <input type="text" name="date" id="date" />
JavaScript : $( "#date" ).datepicker();
111
© 2007 - CEFRIEL
jQueryUI Opzioni
$( "#mySliderDiv" ).slider({
orientation: "vertical",
min: 0,
max: 150,
value: 50
});
112
Progettazione del Tema
n 
n 
n 
jQuery UI offre un tool chiamato ThemeRoller per la
personalizzazione del tema dei widget.
http://jqueryui.com/themeroller/
Theme Roller reindirizza a Download Center per definire il
pacchetto personalizzato da scaricare (quali widget si ha
intenzione di utilizzare) con il nuovo tema definito.
113
NODE.JS
114
Introduzione
n 
n 
n 
Node.js è un framework per realizzare applicazioni Web in
JavaScript.
Con Node.js possiamo sviluppare in javascript lato server
La piattaforma è basata sul Javascript Engine V8 (di
Google)
–  utilizzato anche da Chrome
n 
Caratteristica principale: Approccio asincrono
–  Le risorse del sistema sono acceduta con un approccio eventdriven.
–  E non il classico modello dei web server basato su processi.
115
© 2007 - CEFRIEL
Paradigma Event-driven
n 
n 
n 
n 
n 
n 
Si lancia un’azione quando accade qualcosa.
Ogni azione risulta asincrona e non sequenziale come nei
classici web server.
Basato da un sistema di callback gestito dal runtime.
Vantaggi:Efficienza
Il comportamento asincrono permette all’applicazione può
fare altro.
Questa caratteristica cambia anche l’approccio allo
sviluppo.
116
Esempio
/** approccio sincrono (classico) **/
var dato = ottieniDatoDaRemoto(url);
alert(dato);
/** approccio ad eventi (asincrono) **/
ottieniDatoDaRemoto(url, function(dato) {
alert(dato);
}); //la funzione ritorna subito
117
Creazione di un web server
var http = require('http');
var server = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello Worldn');
})
server.listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
118
NPM
n 
Il registro NPM è il repositori di librerie scritto per node.js
n 
Equivalente a gem in Rails e PEAR in PHP
n 
NPM supporta anche la gestione dell’installazione e delle
versioni.
119
Moduli
n 
Globals include una serie di API nel namespace globale
richiamabili direttamente in tutta l’applicazione.
–  require permette di include moduli aggiuntivi
–  setTimeout e setInterval per i timer
–  include oggetti fondamentali come consolo che permette di
accedere allo std input e std error
n 
http
–  include una serie di oggetti per utilizzare il protocollo e avviare il
server
n 
url
–  definizione dell’url e suo parsing in un oggetto
n 
path
–  accesso a percorsi reali della macchina (navigazione cartelle)
n 
…
120
Utilizzare i moduli nelle app
n 
si utilizza la funzione globale require
var url = require('url');
console.log(url.parse('http://www.google.com'));
console.log(url.format({ host: ’www.google.com', protocol: 'http' }));
n 
require:
–  cerca nella cartella di default node_modules
–  è possibile includere tutto un insieme di moduli raccolto in una
cartella
121
Creazione Modulo
n 
n 
Un modulo è uno o più file contenenti funzioni js
Ogni funzione viene esportata tramite l’oggetto exports
//simplemath.js
var sum = function(a, b) { //definiamo la funzione sum
return a+b;
}
var product = function(a, b) { //definiamo la funzione product
return a*b;
}
var private = function(a,b) {
return "Io sono private!!";
}
exports.sum = sum; //esportiamo la funzione sum
exports.product = product; //esportiamo la funzione product
122
Utilizzo del modulo
//app.js
var sm = require('./simplemath');
console.log(sm.sum(1,2)); //echo 3
console.log(sm.product(1,2)); //echo 2;
console.log(sm.private(1,2)); //error!
123
Dispatcher
n 
Il Dispatcher permette di associare richieste diverse a
funzioni diverse.
var dispatcher = require('httpdispatcher');
dispatcher.onGet("/page1", function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Page One');
});
dispatcher.onPost("/page2", function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Page Two');
});
http.createServer(function (req, res) {
dispatcher.dispatch(req, res);
}).listen(1337, '127.0.0.1');
124
HttpDispatcher
var HttpDispatcher = function() {
this.listeners = { get: [ ], post: [ ] };
}
HttpDispatcher.prototype.on = function(method, url, cb) {
this.listeners[method].push({
cb: cb,
url: url
});
}
HttpDispatcher.prototype.onGet = function(url, cb) {
this.on('get', url, cb);
}
HttpDispatcher.prototype.onPost = function(url, cb) {
this.on('post', url, cb);
}
125
HttpDispatcher
n 
Metodo dispatch e esportazione
HttpDispatcher.prototype.dispatch = function(req, res) {
var parsedUrl = require('url').parse(req.url, true);
var method = req.method.toLowerCase();
this.listener[method][parsedUrl.pathname](req, res);
}
module.exports = new HttpDispatcher();
126
Template System con Bind
dispatcher.onGet('/home', function(req, res, chain) {
bind.toFile('tpl/home.tpl', {
name: 'Alberto',
address: 'via Roma',
city: 'Milano'
}, function(data) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(data);
});
});
/* file tpl/home.tpl */
<h1>(:name ~ Marco:)</h1>
<b>(:address:) - (:city:)</b>
127
Scarica

slides - WordPress.com