Sei sulla pagina 1di 29

Manual de MVC: (1)

FrontController

54

ARQUITEC TURA

Hackers & Developers Magazine Ao 0, Nmero 1

Desde esta segunda edicin de Hackers & Developers


Magazine, damos inicio al Manual de MVC en Python y
PHP. Cada mes, una nueva entrega del manual,
abarcando en detalle, el desarrollo de aplicaciones
Web modulares con el patrn arquitectnico modelovista-controlador. En esta primera entrega, haremos
una introduccin a MVC y hablaremos sobre el
FrontController: el patrn de diseo, que nos
permitir utilizar una arquitectura MVC en sistemas
modulares.

Escrito por: Eugenia Bahit (Arquitecta GLAMP & Agile Coach)


Eugenia es Arquitecta de Software, docente instructora de
tecnologas GLAMP (GNU/Linux, Apache, MySQL, Python y PHP) y
Agile coach (UTN) especializada en Scrum y eXtreme Programming.
Miembro de la Free Software Foundation e integrante del equipo de
Debian Hackers.
Webs:
www.cursosdeprogramacionadistancia.com
www.eugeniabahit.com
Redes sociales:
Twitter / Identi.ca: @eugeniabahit

rontController es el patrn de diseo


requerido para trabajar con MVC, en
arquitecturas modulares, ya que el mismo, permite manejar desde un nico
archivo, las peticiones del usuario, analizarlas e invocar al controlador responsable
de proveer la informacin solicitada al usuario. Pero antes de ir de lleno al
FrontController, haremos una breve introduccin sobre el Patrn Arquitectnico (mal
llamado patrn de de diseo), MVC.

Entendiendo el Patrn Arquitectnico modelo-vistacontrolador


El patrn MVC debe ser entendido desde dos pticas diferentes: la del desarrollador y la

Hackers & Developers Magazine Ao 0, Nmero 1

55

del usuario. Desde el punto de vista del desarrollador, MVC nos permite mantener
individualizadas, las responsabilidades dentro de un sistema, permitindonos
diferenciar y aislar el diseo del sistema (objetos que componen los modelos), de la
interfaz grfica del usuario (GUI) y su correspondiente lgica de negocios (vistas),
utilizando como conector intermediario un objeto controlador.
El orden modelo-vista-controlador, es el que el programador debe seguir en el proceso
de desarrollo del sistema. Sin embargo, desde el punto de vista del usuario, todo
comienza en el controlador. Veamos cmo:

A nivel funcional, en MVC todo se inicia con una solicitud del usuario (peticin);

Dicha solicitud (algo que el usuario quiere hacer con respecto al sistema), es
representada mediante la estructura de la URI;

En una arquitectura modular, la estructura de la URI, guardar la forma:


(dominio)/modulo/modelo/recurso[/argumentos] siendo modulo, modelo y
recurso datos obligatorios y argumentos, opcionales. De esta forma, si un usuario
quisiera agregar una nueva nota de crdito y el modelo (objeto) comprobante,
perteneciese al mdulo de contabilidad, dicha peticin sera realiza a travs de la
siguiente URI: http://mymvcapp.net/contabilidad/comprobante/agregar

Cuando la solicitud del usuario es enviada, sta es recibida por el controlador del
modelo, quien se comunica con ste solicitndole la informacin necesaria;

Una vez que el modelo retorna la informacin al controlador, ste le entrega dicha
informacin a la vista del modelo, quien ser la encargada de procesar la
informacin recibida, colocarla en la GUI y mostrrsela al usuario.

Veamos un ejemplo:
# MODELO: /myapp/modulo/models/vidrio.php
class Vidrio {
function __construct() {
$this->vidrio_id = 0;
$this->color = '';
}
function save() {
# Guarda un nuevo objeto u objeto existente
}
function get() {
# Recupera un objeto
}
function destroy() {
# Destruye un objeto
}
}

2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 1

# MODELO: /myapp/modulo/models/vidrio.py
class Vidrio(object):
def __init__(self):
self.vidrio_id = 0
self.color = ''
def save(self):
"""Guarda un nuevo objeto u objeto existente"""
pass
def get(self):
"""Recupera un objeto"""
pass
def destroy(self):
"""Destruye un objeto"""
pass
# GUI (para PHP): /myapp/static/html/ver_vidrio.html
<h1>Vidrio {vidrio_id}</h1>
<p>Vidrio de color {color}.</p>
# VISTA: /myapp/modulo/views/vidrio.php
class VidrioView {
function ver($objeto=NULL) {
settype($objeto, 'array');
$comodines = array_keys($objeto);
foreach($comodines as &$comodin) {
$comodin = "\{$comodin\}";
}
$valores = array_values($objeto);
$template = file_get_contents("/myapp/static/html/ver_vidrio.html");
print str_replace($comodines, $valores, $template);
}
}

# GUI (para Python): /myapp/static/html/ver_vidrio.html


<h1>Vidrio $vidrio_id</h1>
<p>Vidrio de color $color.</p>
# VISTA: /myapp/modulo/views/vidrio.py
class VidrioView(object):
def ver(self, objeto):
with open("/myapp/static/html/ver_vidrio.html", "r") as archivo:
template = archivo.read()
return Template(template).safe_substitute(vars(objeto))

2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

56

Hackers & Developers Magazine Ao 0, Nmero 1

57

# CONTROLADOR: /myapp/modulo/controllers/vidrio.php
class VidrioController {
function ver($id=0) {
$vidrio = new Vidrio();
$vidrio->vidrio_id = $id;
$vidrio->get();
$view = new VidrioView();
$view->ver($vidrio);
}
}

# CONTROLADOR: /myapp/modulo/controllers/vidrio.py
class VidrioController(object):
def ver(self, id=0):
vidrio = Vidrio()
vidrio.vidrio_id = id
vidrio.get()
view = VidrioView()
self.output = view.ver(vidrio)

Si el usuario quisiera ver el vidrio con id 15, su solicitud sera enviada a travs de:
http://mymvcapp.net/modulo/vidrio/ver/15 y la misma, sera tramitada por
VidrioController, pero cmo llegar la solicitud a VidrioController? Para responder a
esta pregunta, tendremos que hablar de FrontController.

Recibiendo las solicitudes del usuario con FrontController


desde Python
7
En Python (bajo el supuesto que trabajamos con WSGI bajo Apache
) nuestra
application ser quien haga las veces de FrontController. En primer lugar, deber
analizar la URI a fin de obtener el mdulo, modelo, recurso y los argumentos opcionales
que le permitirn conocer a qu controlador debe invocar:

# Divido la URI utilizando como separador la barra diagonal


peticiones = environ['REQUEST_URI'].split('/')
# Elimino el primer elemento puesto que estar vaco
peticiones.pop(0)
# Cuento las peticiones, para saber si hay o no argumentos
7

Si no sabes como codear una Web en Python crudo (sin Frameworks) corriendo bajo Apache, te
recomiendo leer un artculo que publiqu en Debian Hackers Una Web en Python sobre Apache en 3
pasos ingresando en http://www.debianhackers.net/una-web-en-python-sobre-apache-sinframeworks-y-en-solo-3-pasos

2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 1

cantidad = len(peticiones)
# Obtengo el mdulo, modelo, recurso (y argumentos, si existen)
if cantidad == 3:
modulo, modelo, recurso = peticiones
elif cantidad == 4:
modulo, modelo, recurso, arg = peticiones

A continuacin, deber -utilizando los datos obtenidos-, importar el mdulo del


controlador, instanciarlo y entregarle la informacin necesaria para que ste acte:
# Obtengo el nombre del controlador
controller_name = '%sController' % modelo
# Para poder importar el controlador, debo agregar el path de la aplicacin
from sys import path
path.append(environ['SCRIPT_FILENAME'].replace('frontcontroller.py', ''))
# Importo el mdulo del controlador
exec 'from %s.controllers.%s import %s' % (modulo, modelo, controller_name)
# Instancio al controlador y le envo el recurso y argumentos
controller = locals()[controller_name](recurso, arg)
# Capturo la salida
output = controller.output

Finalmente, se llama a start_response() y se retorna la salida, normalmente:


def application(environ, start_response):
peticiones = environ['REQUEST_URI'].split('/')
peticiones.pop(0)
cantidad = len(peticiones)
if cantidad == 3:
modulo, modelo, recurso = peticiones
elif cantidad == 4:
modulo, modelo, recurso, arg = peticiones
controller_name = '%sController' % modelo.capitalize()
from sys import path
path.append(environ['SCRIPT_FILENAME'].replace('frontcontroller.py', ''))
exec 'from %s.controllers.%s import %s' % (modulo, modelo,
controller_name)
controller = locals()[controller_name](recurso, arg)
output = controller.output
start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])
return output

El FrontController, nos obligar a que nuestros controladores, estn preparados para


2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

58

Hackers & Developers Magazine Ao 0, Nmero 1

59

recibir dos parmetros: el recurso (para hacer la llamada dinmica al mtodo actuante) y
el argumento (que pueda ser requerido por algunos mtodos):
class VidrioController(object):
def __init__(self, recurso='', arg=0):
getattr(self, recurso)(int(arg))
def ver(self, id=0):
vidrio = Vidrio()
vidrio.vidrio_id = id
vidrio.get()
view = VidrioView()
self.output = view.ver(vidrio)

Recibiendo las solicitudes del usuario con FrontController


desde PHP
En PHP, el trabajo que debemos dejar preparado para poder actuar, requiere un mayor
esfuerzo. En primer lugar, debemos preparar a nuestro servidor, para trabajar con las
denominadas Friendly URL (URL amigables). Esto requiere:
Habilitar el mdulo rewrite de Apache (debes convertirte en sper usuario):
a2enmod rewrite

Modificar la directiva AllowOverride de nuestro VirtualHost:


AllowOverride All

/etc/apache2/sites(Si utilizas el VirtualHost por defecto, localizars el archivo en


available/default. Ten la precaucin de modificarlo como sper usuario. La directiva
AllowOverride se encuentra dentro del tag Directory) No olvides reiniciar Apache para
que los cambios surjan efecto! service apache2 restart

Y finalmente, crear un archivo .htaccess en el directorio raz de la aplicacin (estar en el


mismo directorio que frontcontroller.php)
# Encender el motor de reescritura de las URL
RewriteEngine On
# Crear una regla que redirija todas las peticiones (excepto las realizadas
# al directorio static) hacia el frontcontroller.php
RewriteRule !(^static) frontcontroller.php

Una vez preparado el terreno, estaremos en condiciones de crear nuestro


FrontController.
Al igual que en Python, el primer paso ser analizar la URI a fin de obtener el mdulo, el
modelo, el recurso y los argumentos que opcionalmente, podra estar enviando el
2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 1

usuario:
# Divido la URI utilizando como separador la barra diagonal
$peticiones = explode('/', $_SERVER['REQUEST_URI']);
# Cuento las peticiones, para saber si hay o no argumentos
$cantidad = count($peticiones);
# Obtengo el mdulo, modelo, recurso (y argumentos, si existen)
if($cantidad == 3) {
list($modulo, $modelo, $recurso) = $peticiones;
} elseif($cantidad == 4) {
list($modulo, $modelo, $recurso, $arg) = $peticiones;
}

Luego, con los datos obtenidos, est en condiciones de importar el archivo del
controlador , instanciarlo y entregarle la informacin necesaria para que ste acte:
# Obtengo el nombre del controlador
$controller_name = ucwords($modelo) . "Controller";
# Para poder importar el controlador, debo agregar el path de la aplicacin
ini_set('include_path', str_replace('frontcontroller.php', '',
$_SERVER['SCRIPT_FILENAME']));
# Importo el mdulo del controlador
require_once("$modulo/controllers/$modelo.php");
# Instancio al controlador y le envo el recurso y argumentos
$controller = new $controller_name($recurso, $arg);

Finalmente, el FrontController deber auto-ejecutarse:


class FrontController {
public static function handler() {
$peticiones = explode('/', $_SERVER['REQUEST_URI']);
$cantidad = count($peticiones);
if($cantidad == 3) {
list($modulo, $modelo, $recurso) = $peticiones;
} elseif($cantidad == 4) {
list($modulo, $modelo, $recurso, $arg) = $peticiones;
}
$controller_name = ucwords($modelo) . "Controller";
ini_set('include_path', str_replace(
'frontcontroller.php', '', $_SERVER['SCRIPT_FILENAME']));
require_once("$modulo/controllers/$modelo.php");
$controller = new $controller_name($recurso, $arg);
}
}
FrontController::handler();

2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

60

Hackers & Developers Magazine Ao 0, Nmero 1

61

Por favor, notar que la directiva ini_set, debera estar en un


archivo de configuracin (un settings.php) y no, dentro del
FrontController.
Nuestro FrontController, ahora nos estar obligando a preparar los controladores de
nuestros mdulos, para recibir dos parmetros: el recurso (para hacer la llamada
dinmica al mtodo actuante) y el argumento (que pueda ser requerido por algunos
mtodos):
class VidrioController {
function __construct($recurso='', $arg=0) {
call_user_func(array($this, $recurso), $arg);
}
function ver($id=0) {
$vidrio = new Vidrio();
$vidrio->vidrio_id = $id;
$vidrio->get();
$view = new VidrioView();
$view->ver($vidrio);
}
}

En la siguiente entrega de MVC en Python y PHP, nos ocuparemos especialmente de las


vistas.

Manual de MVC: (2)


Vistas dinmicas y
Templates

74

M ANUAL DE M VC

Hackers & Developers Magazine Ao 0, Nmero 2

Tanto en Python como en PHP, es posible no embeber


diferentes lenguajes en las plantillas. Incluso, cuando
se trate de resultados trados de una base de datos,
que deban ser sustituidos de forma iterativa. En la
entrega de hoy, aprenderemos las tcnicas que nos
convertirn en Magos del MVC.

Escrito por: Eugenia Bahit (Arquitecta GLAMP & Agile Coach)


Eugenia es Arquitecta de Software, docente instructora de tecnologas
GLAMP (GNU/Linux, Apache, MySQL, Python y PHP) y Agile coach (UTN)
especializada en Scrum y eXtreme Programming. Miembro de la Free
Software Foundation e integrante del equipo de Debian Hackers.
Webs:
Cursos de programacin a Distancia: www.cursosdeprogramacionadistancia.com
Agile Coaching: www.eugeniabahit.com
Redes sociales:
Twitter / Identi.ca: @eugeniabahit

reo que la consulta ms frecuente que he recibido desde que publiqu mi libro
POO y MVC en PHP, ha sido cmo evitar embeber cdigo de programacin en el
HTML para completar una tabla o lista de seleccin ( select) con los resultados de
una consulta a base de datos. Y cranme: es sumamente sencillo.
Primero, es necesario saber, que existen tres tipos de sustituciones que pueden
efectuarse en las vistas:
1. Sustituciones estticas: es el caso de una plantilla HTML en la que se deben
sustituir ciertos datos de forma esttica. Es decir, plantillas HTML en las que cada
indicador de sustitucin, debe ser reemplazado por un valor concreto.
2. Sustituciones dinmicas: son aquellas plantillas HTML en las cules un mismo
indicador de sustitucin, debe ser reemplazado de forma iterativa por ms de un
dato. Por ejemplo, una lista de seleccin que deba reemplazarse con los
resultados devueltos por una consulta de seleccin mltiple a base de datos.
2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 2

75

3. Sustituciones combinadas: son aquellas plantillas HTML en las que se debe


realizar tanto una sustitucin esttica como una (o ms) sustituciones dinmicas.

Pasemos lo anterior a ejemplos prcticos:


Plantilla de sustitucin esttica:
<!doctype html>
<html lang="es">
<head>
<charset="utf-8">
<title>[INDICADOR_DE_SUSTITUCION: TITULO]</title>
</head>
<body>
<header>
<h1>[INDICADOR_DE_SUSTITUCION: TITULO]</h1>
</header>
<article>
[INDICADOR_DE_SUSTITUCION: CONTENIDO]
</article>
</body>
</html>

Plantilla de sustitucin dinmica:


<!doctype html>
<html lang="es">
<head>
<charset="utf-8">
<title>Listado telefnico</title>
</head>
<body>
<header>
<h1>Listado telefnico</h1>
</header>
<table>
<tr>
<th>Nombre</th>
<th>Apellido</th>
<th>Telfono</th>
</tr>
<!--SUSTITUCION-DINAMICA-->
<tr>
<td>[INDICADOR_DE_SUSTITUCION: NOMBRE]</td>
<td>[INDICADOR_DE_SUSTITUCION: APELLIDO]</td>
<td>[INDICADOR_DE_SUSTITUCION: TELFONO]</td>
</tr>
<!--SUSTITUCION-DINAMICA-->
</table>
</body>
</html>

2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 2

76

Plantilla de sustitucin combinada:


<!doctype html>
<html lang="es">
<head>
<charset="utf-8">
<title>[INDICADOR_DE_SUSTITUCION: TITULO]</title>
</head>
<body>
<header>
<h1>[INDICADOR_DE_SUSTITUCION: TITULO]</h1>
</header>
<article>
[INDICADOR_DE_SUSTITUCION: CONTENIDO]
</article>
<h3>Listado telefnico</h3>
<table>
<tr>
<th>Nombre</th>
<th>Apellido</th>
<th>Telfono</th>
</tr>
<!--SUSTITUCION-DINAMICA-->
<tr>
<td>[INDICADOR_DE_SUSTITUCION: NOMBRE]</td>
<td>[INDICADOR_DE_SUSTITUCION: APELLIDO]</td>
<td>[INDICADOR_DE_SUSTITUCION: TELFONO]</td>
</tr>
<!--SUSTITUCION-DINAMICA-->
</table>
</body>
</html>

Indicadores de sustitucin en las GUI


Los indicadores de sustitucin, son marcas de texto plano que se colocan en los archivos
HTML para identificar las zonas de la plantilla, en las cules deben reemplazarse ciertos
datos.

En Python, los identificadores de sustitucin se expresan con palabras concatenadas


antecedidas del signo dlar ($):
<!doctype html>
<html lang="es">
<head>
<charset="utf-8">
<title>$titulo</title>
</head>
<body>
<header>
2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 2

77

<h1>$titulo</h1>
</header>
<article>
$contenido
</article>
</body>
</html>

Mientras que en PHP, no existe ninguna regla al respecto, quedando al libre albedro del
diseador, la eleccin de estilo de los identificadores de sustitucin. Un clsico en los
identificadores de sustitucin en PHP, es encerrar las palabras identificadoras entre
dos llaves, de apertura y cierre respectivamente {}:
<!doctype html>
<html lang="es">
<head>
<charset="utf-8">
<title>{titulo}</title>
</head>
<body>
<header>
<h1>{titulo}</h1>
</header>
<article>
{contenido}
</article>
</body>
</html>

Lgica de sustitucin en MVC


La lgica de las vistas en MVC, es nica y exclusiva para cada GUI en particular. No
obstante, existe un procedimiento estndar, el cual consta de tres pasos:
1. Obtener el HTML (GUI);
2. Crear un diccionario con los identificadores de sustitucin y los datos asociados a
su reemplazo;
3. Realizar la sustitucin de datos sobre la plantilla HTML e imprimirla en pantalla
(es decir, mostrar el resultado al usuario).

Obtener la GUI en PHP:


$plantilla = file_get_contents('/ruta/a/template.html');

Obtener la GUI en Python:


with open('/ruta/a/template.html', 'r') as archivo:
2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 2

78

plantilla = archivo.read()

Crear un diccionario de sustituciones en PHP:


$diccionario = array(
'{titulo}'=>'Pgina de muestra',
'{contenido}'=>'Hola Mundo'
);

Crear un diccionario de sustituciones en Python:


diccionario = dict(
titulo='Pgina de prueba',
contenido='Hola Mundo'
)

Por favor, notar que en Python, el nombre de las claves del


diccionario es el identificador de sustitucin SIN el signo
dlar, mientras que en PHP, las claves del diccionario
debern verse exactamente igual a los identificadores de
sustitucin utilizados en la plantilla HTML.
Sustitucin de diccionarios en PHP:
$render = str_replace(array_keys($diccionario),
array_values($diccionario), $plantilla);

Sustitucin de diccionarios en Python:


from string import Template
render = Template(plantilla).safe_substitute(diccionario)

Sustituciones estticas
Tanto en Python como en PHP, las sustituciones estticas se realizan siguiendo los tres
pasos estndar mencionados en el punto anterior: traer la plantilla, crear el diccionario y
realizar la sustitucin.
Si los datos sustitutos debieran traerse desde una consulta a base de datos, primero
se realizar la consulta SQL, luego se almacenarn los datos retornados en variables y,
finalmente, dichas variables se asignarn como valores de las claves del diccionario, sin
ms complejidad que sta.

2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 2

79

Sustituciones dinmicas
En las sustituciones dinmicas, la mayor complejidad radica en la obtencin del cdigo
HTML sobre el cual la sustitucin debe realizarse.
La plantilla HTML se deber obtener de forma estndar, mientras que de ella, antes de
proceder con los dos pasos siguientes, se deber recuperar slo la fraccin de cdigo
HTML sobre la cul realizar los reemplazos. Dicha fraccin de cdigo, se obtendr
definiendo previamente, la siguiente expresin regular:
<!--NOMBRE-DE-LA-SUSTITUCION-DINAMICA-->(.|\n){1,}<!--NOMBRE-DE-LA-SUSTITUCION-DINAMICA-->

Dnde NOMBRE-DE-LA-SUSTITUCION-DINAMICA ser el texto utilizado en el cdigo HTML


dentro del comentario identificador:
Dado el siguiente identificador de sustitucin dinmica:
<!--TELEFONOS-->
... cdigo html a iterar + indicadores de sustitucin
<!--TELEFONOS-->

La expresin regular debera verse como la siguiente:


<!--TELEFONOS-->(.|\n){1,}<!--TELEFONOS-->

Obtencin del cdigo HTML iterativo en PHP:


$regex = "/<!--TELEFONOS-->(.|\n){1,}<!--TELEFONOS-->/";
preg_match($regex, $plantilla, $matches); # $matches se define al vuelo
$match = $matches[0];

Obtencin del cdigo HTML iterativo en Python:


import re
regex = re.compile("<!--TELEFONOS-->(.|\n){1,}<!--TELEFONOS-->")
match = regex.search(plantilla).group(0)

Una vez obtenido el match (fragmento de cdigo HTML coincidente con la expresin
regular), tanto el diccionario como las sustituciones, debern realizarse de manera
estndar pero dentro de un bucle, condicionado por la cantidad de registros obtenidos
de la consulta SQL. La nica salvedad, es que ambos pasos debern realizarse en la
misma estructura de control cclica y, el resultado de cada sustitucin, sumarse dentro de
una misma variable. La sustitucin, en este caso, se efectuar sobre el match y no sobre la
plantilla.
Sustitucin iterativa en PHP:
$render = "";
foreach($registros as $array) {
$diccionario = array(
"{nombre}"=>$array[0],
"{apellido}"=>$array[1],
"{telefono}"=>$array[2]
);
$render .= str_replace(array_keys($diccionario),
2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

Hackers & Developers Magazine Ao 0, Nmero 2

80

array_values($diccionario), $match);

Sustitucin iterativa en Python:


render = ""
for tupla in registros:
diccionario = dict(
nombre=tupla[0],
apellido=tupla[1],
telefono=tupla[2]
)
render += Template(match).safe_substitute(diccionario)

Finalmente, deber sustituirse el match por el render en la plantilla.


Sustitucin del match por el render en PHP:
$render_final = str_replace($match, $render, $plantilla);

Sustitucin del match por el render en Python:


render_final = plantilla.replace(match, render)

Si no se desea conservar los comentarios HTML identificadores de la sustitucin


dinmica (lo ms recomendado), los mismos, se podrn reemplazar mediante la funcin
str_replace en PHP y el mtodo replace del objeto string de Python.

Sustituciones combinadas
Cuando en una misma plantilla se necesite efectuar una sustitucin esttica y una o ms
sustituciones dinmicas, el proceso se har paso a paso. Esto significa, que en primer
render, deber
lugar, se efectuar la sustitucin esttica. El resultado obtenido en ese
match para la sustitucin dinmica. Es decir, que
ser aquel sobre el cul se realice el
cuando se llegue al proceso de sustitucin dinmica, no se volver a traer la plantilla,
sino que se utilizar el cdigo ya renderizado, obtenido en el proceso de sustitucin
esttica.

Tip by Commander in Chief:


Evita utilizar servicios en lnea para obtener un hash
determinado. Estos servicios guardan la cadena ingresada
asocindola al hash resultante y se utilizan para efectuar el
proceso de ingeniera inversa sobre un hash, a fin de obtener
la cadena original.

2012 Hackers & Developers Magazine Creative Commons Atribucin NoComercial CompartirIgual 3.0. www.hdmagazine.org

32

Manual de MVC: (3)


Los objetos View

MANUAL DE MVC

Hackers & Developers Magazine Ao 0, Nmero 3

En el captulo anterior, vimos como identificar los


diferentes tipos de sustituciones que desde las vistas
de los modelos, en MVC, pueden realizarse. En esta
entrega veremos como crear los objetos View de cada
modelo, los cules implementarn todo lo aprendido
en el captulo anterior.

Escrito por: Eugenia Bahit (Arquitecta GLAMP & Agile Coach)


Eugenia es Arquitecta de Software, docente instructora de tecnologas
GLAMP (GNU/Linux, Apache, MySQL, Python y PHP) y Agile coach (UTN)
especializada en Scrum y eXtreme Programming. Miembro de la Free
Software Foundation e integrante del equipo de Debian Hackers.
Webs:
Cursos de programacin a Distancia: www.cursosdeprogramacionadistancia.com
Web personal: www.eugeniabahit.com
Redes sociales:
Twitter / Identi.ca: @eugeniabahit

n el captulo anterior, estuvimos viendo ejemplos de los diferentes algoritmos que


pueden utilizarse tanto en Python como en PHP, para realizar sustituciones
estticas y dinmicas (render) en los archivos HTML.

Dichos algoritmos, formarn parte de los mtodos de cada una de las vistas, pudiendo
adems, crearse objetos View a nivel del core, para ser reutilizados en las vistas de cada
modelo.

En MVC, cada modelo debe contar con una vista (objeto


ModelView)
En principio, debemos saber que para cada modelo debe haber un objeto vista (objeto
View). Sin embargo, no todos los recursos, debern tener un mtodo en la vista (pero s,
en el controlador del modelo, que veremos ms adelante).
Cuando en MVC se poseen las funcionalidades propias de un ABM, como agregar,
modificar y eliminar un objeto, las vistas, debern tener al menos, dos mtodos: uno
para mostrar el formulario de alta y otro, para mostrar el formulario de edicin. En los

ABM, tambin son frecuentes otros dos mtodos: uno para mostrar el listado de una
coleccin de objetos determinada y otro, para visualizar un objeto puntual. Por
supuesto, la cantidad de mtodos de una vista, depende solo y exclusivamente de los
requerimientos grficos de cada aplicacin. No obstante, el objetivo de esta entrega, es
ver como crear los objetos View. Luego, la cantidad de mtodos a desarrollar,
depender del lector y de los requerimientos de su GUI.
Los mtodos de la vista, sern invocados por el controlador del modelo. ste, ser quien
entregue los datos a la vista, mientras que la ltima, ser la encargada de realizar las
sustituciones pertinentes e imprimir el resultado de las mismas en pantalla.
Bsicamente, la secuencia podra describirse como la siguiente:
1. El usuario solicita un recurso a travs del navegador
2. El FrontController (descrito en la edicin #1), analiza la peticin del usuario e
instancia al controlador correspondiente (veremos controladores ms adelante)
3. El constructor de cada controlador, es quien realiza una llamada de retorno a un
mtodo propio el cual se encargar de:

Instanciar al modelo correspondiente (aunque generalmente, esta


instancia se realiza desde el constructor en la mayora de los casos)

Realizar las modificaciones necesarias sobre el modelo (modificar


propiedades, llamar a los mtodos necesarios, etc.)

Entregar los datos retornados por el modelo a un mtodo de la vista.

4. La vista, traer las plantillas necesarias, para sustituir los datos que le han sido
entregados por el controlador. Finalmente, imprimir en pantalla, el resultado de
dicha sustitucin.

Antes de continuar, si an no lo has hecho, te recomiendo


leer la segunda entrega del manual de MVC 14 y practicar
con los ejemplos all descritos, a fin de poder comprender
mejor, todo lo expuesto en este artculo
Cmo bien se coment, debe existir una vista (objeto View) por cada modelo. El nombre
de cada vista, generalmente, ser el nombre del modelo, seguido de la palabra View.
Vidrio, Marco y Ventana, tendremos 3 vistas:
Por ejemplo, dados los modelos:
VidrioView, MarcoView y VentanaView:
# en PHP
class VidrioView {
}

14 http://www.hdmagazine.org/?magazine=HackersAndDevelopers&num=2

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 33

# en Python
class VidrioView(object):
pass

Suponiendo que para nuestro modelo Vidrio hayamos definido un recurso agregar (que
deber ser un mtodo del controlador, como veremos ms adelante), en principio,
debemos contar con la GUI para este recurso (aqu no incluiremos an la plantilla
general, sino solo el contenido relativo a este recurso. La plantilla general se incluir al
final de este artculo):
<h3>Agregar un nuevo vidrio</h3>
<form method="POST" action="/mimodulo/vidrio/guardar">
<!-- notar que el nombre de los campos, debe coincidir con el nombre de las
propiedades del objeto, siempre que esto sea posible-->
<label for="grosor">Grosor:</label><br/>
<input type="text" name="grosor" id="grosor" size="3"/> mm<br/><br/>
<label for="sup">Superficie:</label><br/>
<input type="text" name="superficie" id="sup"/><br/><br/>
<label for="color">Color:</label><br/>
<input type="text" name="color" id="color"/><br/><br/>
<input type="submit" value="Guardar"/>
</form>

Como podemos observar, la GUI siempre debe ser el primer paso en el proceso de
desarrollo de las vistas.
En este ejemplo en particular, nos encontramos con que la GUI, no requiere de ninguna
sustitucin (ni esttica ni dinmica). Entonces, lo nico que necesitaremos tener en la
lgica de nuestra vista, es un mtodo que traiga dicha GUI y la muestre en pantalla. Este
agregar(). Podra tener un nombre ms
mtodo, no necesariamente debe llamarse
descriptivo como por ejemplo, mostrar_form_alta():
# PHP: Archivo /myapp/modulo/views/vidrio.php
class VidrioView {
function __construct() {
}
function mostrar_form_alta() {
$plantilla = file_get_contents("/ruta/a/agregar_vidrio.html");
print $plantilla;
}
}

# Python: Archivo /myapp/modulo/views/vidrio.py


class VidrioView(object):
def __init__(self):
pass

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 34

def mostrar_form_alta(self):
with open("/ruta/a/agregar_vidrio.html", "r") as archivo:
plantilla = archivo.read()
print plantilla

guardar (ver atributo


Cuando el formulario sea enviado, ser solicitado el recurso
action del formulario HTML). Este recurso, ser procesado por el controlador pero
qu haremos finalmente con el usuario? El controlador, podr decidir que sera una
buena idea, mostrarle el objeto creado, al usuario. En ese caso, deber existir un recurso
ver que tambin ser manejado por el controlador (al igual que todos los recursos). El
recurso ver ser un mtodo del controlador. ste, se encargar de recuperar el objeto
Vidrio recin creado y entregrselo a la vista para que haga lo suyo. Entonces qu
debemos tener primero? La GUI, igual que siempre:
<!-- GUI para PHP -->
<h3>Vidrio ID {vidrio_id}</h3>
<b>Grosor:</b> {grosor} mm<br/>
<b>Superficie:</b> {superficie}<br/>
<b>Color:</b> {color}

<!-- GUI para Python -->


<h3>Vidrio ID $vidrio_id</h3>
<b>Grosor:</b> $grosor mm<br/>
<b>Superficie:</b> $superficie<br/>
<b>Color:</b> $color

En este caso, la vista deber contar con un mtodo, que se encargue de realizar una
sustitucin esttica. Para esto, el controlador, le deber pasar un objeto Vidrio como
parmetro. Ampliemos el ejemplo anterior:
# PHP: Archivo /myapp/modulo/views/vidrio.php
class VidrioView {
function __construct() {
}
function mostrar_form_alta() {
$plantilla = file_get_contents("/ruta/a/agregar_vidrio.html");
print $plantilla;
}
function mostrar_objeto($objeto_vidrio) {
# Traigo la plantilla
$plantilla = file_get_contents("/ruta/a/ver_vidrio.html");
# Creo el diccionario
settype($objeto_vidrio, 'array');
foreach($objeto_vidrio as $clave=>$valor) {
$objeto_vidrio["{{$clave}}"] = $valor;

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 35

unset($objeto_vidrio[$clave]);
}
# Realizo la sustitucin
$render = str_replace(array_keys($objeto_vidrio),
array_values($objeto_vidrio), $plantilla);
# Imprimo el resultado en pantalla
print $render;
}
}

# Python: Archivo /myapp/modulo/views/vidrio.py


from string import Template
class VidrioView(object):
def __init__(self):
pass
def mostrar_form_alta(self):
with open("/ruta/a/agregar_vidrio.html", "r") as archivo:
plantilla = archivo.read()
print plantilla
def mostrar_objeto(self, objeto_vidrio):
# Traigo la plantilla
with open("/ruta/a/ver_vidrio.html", "r") as archivo:
plantilla = archivo.read()
# Creo el diccionario
diccionario = vars(objeto_vidrio)
# Realizo la sustitucin
render = Template(plantilla).safe_substitute(diccionario)
# Retorno el resultado
# para que application lo imprima en pantalla
return render

Luego, si el resultado obtenido, se desea imprimir dentro de una plantilla general


(plantilla de base), solo ser cuestin de crear un mtodo show() en una vista a nivel del
core. La plantilla general, deber contar con al menos un parmetro de sustitucin para
show() el valor de
el contenido y ser la vista de cada modelo, quien le pase a
sustitucin del mismo para finalmente, imprimir en pantalla el resultado retornado por
show(). Aqu, una vez ms, debemos contar previamente con la GUI:
<!-- PLANTILLA HTML PARA PHP -->
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="/static/css/style.css"/>

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 36

<link rel="icon" href="/static/img/favicon.png" type="image/png"/>


<title>{APP_TITLE}</title>
</head>
<body>
<header>
<h1>{APP_TITLE}: {MODULE_TITLE}</h1>
<nav>
<a href="/">{APP_TITLE}</a> &gt;
<a href="/{MODULO}">{MODULE_TITLE}</a> &gt;
<a href="/{MODULO}/{MODELO}">{MODEL_TITLE}</a> &gt;
<b>{RESOURCE_TITLE}</b>
</nav>
</header>
<section>
<!-- aqu ir el contenido sustituido por la vista -->
{CONTENIDO}
</section>
<footer>
&copy; 2013 HDMagazine.org - GPL v3.0
</footer>
</body>
</html>

<!-- PLANTILLA HTML PARA PYTHON -->


<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="/static/css/style.css"/>
<link rel="icon" href="/static/img/favicon.png" type="image/png"/>
<title>$APP_TITLE</title>
</head>
<body>
<header>
<h1>$APP_TITLE: $MODULE_TITLE</h1>
<nav>
<a href="/">$APP_TITLE</a> &gt;
<a href="/$MODULO">$MODULE_TITLE</a> &gt;
<a href="/$MODULO/$MODELO">$MODEL_TITLE</a> &gt;
<b>$RESOURCE_TITLE</b>
</nav>
</header>
<section>
<!-- aqu ir el contenido sustituido por la vista -->
$CONTENIDO
</section>
<footer>
&copy; 2013 HDMagazine.org - GPL v3.0
</footer>
</body>
</html>

A nivel del core, se podr tener una vista para la sustitucin de la plantilla general. La
misma, podr realizarse mediante la llamada esttica a un mtodo de clase o a una
funcin (fuera del contexto de una clase). Aqu, lo haremos en el contexto de una clase.
Crear una clase con un mtodo esttico, es una buena alternativa para centralizar
cualquier otro mtodo relacionado con las vistas, directamente disponible desde el
ncleo de la aplicacin.
2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 37

Por favor, notar que en los siguientes ejemplos, la constante


APP_TITLE se supone definida en un archivo settings

# Archivo: /myapp/core/view.php
class CoreView {
public static function show($modulo, $modelo, $recurso, $render) {
$plantilla = file_get_contents("/ruta/a/template.html");
$diccionario = array(
"{APP_TITLE}" => APP_TITLE,
"{MODULE_TITLE}" => ucwords($modulo),
"{MODULO}" => $modulo,
"{MODELO}" => $modelo,
"{MODEL_TITLE}" => ucwords($modelo),
"{RESOURCE_TITLE}" => ucwords("$recurso $modelo"),
"{CONTENIDO}" => $render
);
print str_replace(array_keys($diccionario), array_values($diccionario),
$plantilla);
}
}

# Archivo: /myapp/core/view.py
class CoreView(object):
def __init__(cls):
pass
def show(cls, modulo, modelo, recurso, render) {
with open("/ruta/a/template.html", "r") as archivo:
plantilla = archivo.read()
diccionario = dict(
APP_TITLE=APP_TITLE,
MODULE_TITLE=modulo.title(),
MODULO=modulo,
MODELO=modelo,
MODEL_TITLE=modelo.title(),
RESOURCE_TITLE="%s %s" % (recurso.title(), modelo.title()),
CONTENIDO=render
)
return Template(plantilla).safe_substitute(diccionario)

Luego, solo ser necesario que cada una de las vistas, en vez de imprimir el resultado de
la sustitucin en pantalla, imprima el resultado de la llamada esttica al mtodo show()
de CoreView:
# PHP: Modificacin del archivo /myapp/modulo/views/vidrio.php
function mostrar($objeto_vidrio) {
$plantilla = file_get_contents("/ruta/a/ver_vidrio.html");
settype($objeto_vidrio, 'array');

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 38

foreach($objeto_vidrio as $clave=>$valor) {
$objeto_vidrio["{{$clave}}"] = $valor;
unset($objeto_vidrio[$clave]);
}
$render = str_replace(array_keys($objeto_vidrio),
array_values($objeto_vidrio), $plantilla);
# Se imprime el resultado de la llamada esttica al mtodo show()
print CoreView::show('modulo', 'vidrio', 'ver detalles de', $render);
}

# Python: Modificacin del archivo /myapp/modulo/views/vidrio.py


def mostrar(self, objeto_vidrio):
with open("/ruta/a/ver_vidrio.html", "r") as archivo:
plantilla = archivo.read()
diccionario = vars(objeto_vidrio)
render = Template(plantilla).safe_substitute(diccionario)
# Retorno el resultado de la llamada esttica al mtodo show()
return CoreView().show('modulo', 'vidrio', 'ver detalles de', render)

Siempre digo a mis alumnos, que el arte de las vistas en


MVC, consiste en lograr convertir lo que se tiene, en lo que
se necesita

Generalmente, siempre se tendr un objeto y lo que se necesitar, ser un diccionario formado por pares de
clave-valor, donde los valores, no sean del tipo coleccin (es decir, sean de un tipo de datos simple). Convertir
un objeto en un diccionario, es la base de la lgica de las vistas en MVC.
En la prxima entrega, nos enfocaremos en los controladores de los modelos,
para ir finalizando nuestro Manual de MVC en Python y PHP.

17

Manual de MVC: (3)


Controladores

M ANUAL DE MVC

Hackers & Developers Magazine Ao 0, Nmero 4

En la primera entrega del manual, estuvimos viendo


como crear el controlador principal de la aplicacin.
Aprendimos cmo ste, se comunicaba de forma
directa
con
el
controlador
del
modelo
correspondiente, actuando de ruteador de los
recursos. En esta entrega final nos concentraremos
en las responsabilidades de los controladores y en los
casos en las que stas intervienen.

Escrito por: Eugenia Bahit (Arquitecta GLAMP & Agile Coach)


Eugenia es Arquitecta de Software, docente instructora de tecnologas
GLAMP (GNU/Linux, Apache, MySQL, Python y PHP) y Agile coach (UTN)
especializada en Scrum y eXtreme Programming. Miembro de la Free
Software Foundation e integrante del equipo de Debian Hackers.
Webs:
Cursos de programacin a Distancia: www.cursosdeprogramacionadistancia.com
Web personal: www.eugeniabahit.com
Redes sociales:
Twitter / Identi.ca: @eugeniabahit

n la primera entrega del Manual de MVC publicada en Hackers & Developers


Magazine Nro. 1, hablamos de FrontController y aprendimos que ste acta de
ruteador de cada recurso, instanciando directamente al controlador del modelo.

Como recordarn, cada controlador debera estar preparado -desde su mtodo


constructor- para realizar una llamada de retorno al recurso correspondiente. Dicha
accin, se encontraba en relacin directa a la instancia generada por FrontController.
La idea de esta ltima entrega en concentrarnos en los recursos que los controladores
de los modelos suelen manejar, sus responsabilidades y los casos en las que las mismas
intervienen.

Caractersticas de los controladores


Todo controlador llevar el nombre del modelo, seguido de la palabra Controller:
# En Python

class VidrioController(object):
pass
# En PHP
class VidrioController { }

Todo controlador debe preparar su mtodo constructor para recibir al menos 2


parmetros en la instancia que realice el FrontController:
# En PHP
class VidrioController {
function __construct($recurso='', $argumento) {
}
}

FrontController le entregue un
En el caso de Python, adems, ser muy til que el
tercer parmetro: el diccionario environ para que el controlador pueda recuperar los
POST) a travs de la clave
wsgi.input (si
datos enviados desde los formularios (va
existe). En este caso, el controlador, deber disponer de dicho valor en una propiedad:

Por favor, notar que esto es solo necesario si se est trabajando en el supuesto de WSGI sobre Apache.

# En Python
class VidrioController(object):
def __init__(self, recurso='', argumento=0, environ={}):
self.pd = env['wsgi.input'].read() if 'wsgi.input' in environ else ''

Los mtodos constructores debern realizar una llamada de retorno a los recursos
correspondientes, pasndoles el argumento como parmetro:
# En Python
class VidrioController(object):
def __init__(self, recurso='', argumento=0, environ={}):
self.pd = env['wsgi.input'].read() if 'wsgi.input' in environ else ''
getattr(self, recurso)(int(argumento))
# En PHP
class VidrioController {
function __construct($recurso='', $argumento) {
call_user_func(array($this, $recurso), $argumento);

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 18

}
}

Los mtodos de los controladores, representarn los recursos disponibles:


# En Python
class VidrioController(object):
def __init__(self, recurso='', argumento=0, environ={}):
self.pd = env['wsgi.input'].read() if 'wsgi.input' in environ else ''
getattr(self, recurso)(int(argumento))
def agregar(self, *arg):
pass
def guardar(self, *arg):
pass
def ver(self, id=0):
pass
# En PHP
class VidrioController {
function __construct($recurso='', $argumento) {
call_user_func(array($this, $recurso), $argumento);
}
function agregar() { }
function guardar() { }
function ver($id=0) { }
}

Bsicamente existen 5 tipos de recursos estndar:


agregar()
editar(id)
guardar()
eliminar(id)
listar()
ver(id)

Muestra el formulario para crear un nuevo objeto


Muestra el formulario para modificar un objeto existente
Guarda los cambios realizados a travs de editar() y agregar()
Elimina un objeto existente
(opcional) Muestra la coleccin completa de objetos basados en el
mismo modelo
(opcional) Permite ver los datos de un objeto

Los recursos editar(), eliminar() y ver() suelen recibir la ID del objeto como
parmetro (argumento recibido desde FrontController).

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 19

Responsabilidades de los controladores


1. Llamar al modelo (crear instancia). Generalmente en los recursos
guardar, eliminar y listar (en este ltimo caso, llamar al colector).

editar,

2. Sanear y asegurar los datos recibidos desde el usuario ANTES de modificar el


modelo: el saneamiento y aseguracin de datos recibidos por el usuario, est en
manos de los controladores y NO de los modelos.
3. Modificar sus propiedades cuando sea necesario. Generalmente en los recursos
donde realiza llamadas al modelo.
4. Hacer las llamadas (al) a los mtodos correspondientes del modelo. De igual
forma que los anteriores, en los casos en los que se llama al modelo y se lo
modifica.
5. Entregar los datos obtenidos a la vista:

En el recurso agregar, suele llamar directamente a la vista sin pasar datos;

En los recursos editar, ver y listar, entrega los datos del objeto a la
vista;

En los recursos eliminar y guardar, suele pasar de largo a la vista y en


cambio, redirige al usuario hacia otro recurso.

Cmo se ven los mtodos de un controlador?


Un ejemplo con cdigo comentado:

# En Python
class VidrioController(object):
def __init__(self, recurso='', argumento=0, environ={}):
self.pd = env['wsgi.input'].read() if 'wsgi.input' in environ else ''
getattr(self, recurso)(int(argumento))
def agregar(self, *arg):
# Llama directamente a la vista
vista = VidrioView()
self.output = vista.mostrar_form_alta()
def editar(self, id=0):
# Instancia al modelo
modelo = Vidrio()
# Modifica las propiedades necesarias
modelo.vidrio_id = int(id)
# Llama al mtodo correspondiente (necesita recuperar el objeto)
modelo.get()
# Le entrega la informacin a la vista
vista = VidrioView()
self.output = vista.mostrar_form_edicion(modelo)
def guardar(self, *arg):

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 20

# Obtiene los datos enviados del el formulario


# Esto generalmente debe hacerse desde un Helper
post = self.pd.split('&')
_POST = {}
for par in post:
field, value = par.split('=')
_POST[field] = value
# Instancia al modelo
modelo = Vidrio()
# Modifica las propiedades necesarias
modelo.vidrio_id = int(_POST['vidrio_id'] if 'vidrio_id' in _POST else 0
modelo.color = _POST['color']
# Llama al mtodo correspondiente (necesita guardar el objeto)
modelo.save()
# Pasa de largo a la vista y en cambio, recurre a otro recurso
self.listar()
def eliminar(self, id=0):
# Instancia al modelo
modelo = Vidrio()
# Modifica las propiedades necesarias
modelo.vidrio_id = int(id)
# Llama al mtodo correspondiente (necesita destruir al objeto)
modelo.destroy()
# Pasa de largo a la vista y en cambio, recurre a otro recurso
self.listar()
def listar(self, *arg):
# Recurre al colector para traer toda la coleccin de objetos Vidrio
coleccion = VidrioCollector().get()
# Le entrega la informacin a la vista
vista = VidrioView()
self.output = vista.mostrar_listado(coleccion)

# En PHP
class VidrioController {
function __construct($recurso='', $argumento=0) {
call_user_func(array($this, $recurso), $argumento);
}
function agregar() {
# Llama directamente a la vista
$vista = new VidrioView();
$vista->mostrar_form_alta();
}
function editar($id=0) {
# Instancia al modelo
$modelo = new Vidrio();
# Modifica las propiedades necesarias
$modelo->vidrio_id = (int)$id;
# Llama al mtodo correspondiente (necesita recuperar el objeto)
$modelo->get();
# Le entrega la informacin a la vista
$vista = new VidrioView();
$vista->mostrar_form_edicion($modelo);
}

2013 HDMagazine.org Creative Commons Atribucin NoComercial CompartirIgual 3.0 Unported

Pg. 21

function guardar() {
# Instancia al modelo
$modelo = Vidrio()
# Modifica las propiedades necesarias
$id = isset($_POST['vidrio_id']) ? (int)$_POST['vidrio_id'] : 0;
$modelo->vidrio_id = $id;
$modelo->color = $_POST['color'];
# Llama al mtodo correspondiente (necesita guardar el objeto)
$modelo->save();
# Pasa de largo a la vista y en cambio, recurre a otro recurso
$this->listar();
}
function eliminar($id=0) {
# Instancia al modelo
$modelo = new Vidrio();
# Modifica las propiedades necesarias
$modelo->vidrio_id = (int)$id;
# Llama al mtodo correspondiente (necesita destruir al objeto)
$modelo->destroy();
# Pasa de largo a la vista y en cambio, recurre a otro recurso
$this->listar();
}
function listar() {
# Recurre al colector para traer toda la coleccin de objetos Vidrio
$coleccion = VidrioCollector::get();
# Le entrega la informacin a la vista
$vista = new VidrioView();
$vista->mostrar_listado($coleccion);
}
}

Potrebbero piacerti anche