*Contenidos*:
.. contents:: :local:
Adaptado y traducido de `from PHP to web2py`_ Es dificil comparar a PHP a un
framework como web2py, y sería más justo compararlo con un framework basado
en PHP (como CakePHP). De todas formas esto no se trata de una simple
comparación. Simplemente queremos explicar web2py a programadores PHP...
Introducción
-------------
En PHP un requerimiento HTTP para "/test.php" es mapeado al archivo
correspondiente, el archivo es ejecutado y la salida es retornada como una
página web.
En web2py un requerimiento HTTP para "/app/c/f" es mapeado a una llamada a la
función f() en el archivo (Controlador) c.py en la aplicación "app". El
archivo c.py está escrito en Python. La salida de la función f() puede ser
una cadena (en ese caso es retornada), o un conjunto de variables
(implementadas como un diccionario Python). En el último caso las variables
son representados en HTML por un archivo c/f.html, llamado Vista. Hay un
tercer tipo de archivo llamado Modelo donde se describe la conexión a la base
de datos, tablas y consultas de una manera independiente del tipo de base de
datos usada. Los tipos de archivos son identificados por las carpetas:
models/ controllers/ views/
Esta jerarquía de archivo es más compleja que en PHP, pero es un pequeño
precio a pagar para mantener sus archivos organizados y legible, y sus
aplicaciones será mucho más fáciles de mantener.
Archivos PHP y vistas web2py
----------------------------
Las Vistas son muy similar a los archivos PHP. Por ejemplo, el siguiente
código PHP::
";
}
?>
Podría ser servido por una función de Controlador elemental como::
def index(): return dict()
y asociado a un archivo de Vista index.html que contiene::
{{for i in range(5):}}
{{='hola mundo'}}
{{pass}}
Notar que
- ambos PHP y web2py le permiten poner código dentro del HTML
- En PHP ud. esta forzado a poner la lógica de su aplicación y
consultas a la base de datos en el mismo archivo que contiene el HTML
mezclando entonces el modelo de los datos con el flujo de trabajo y la
presentación de los datos. En web2py hay tres componentes separados en
distintas carpetas.
- En PHP ud. es forzado a poner en el código el HTML en cadenas (
en este ejemplo). En web2py nunca necesita hacer eso.
- Como en PHP, en web2py puede poner cualquier código que quiera en los
archivos .html pero debería intentar poner solo código de presentación
allí.
- En PHP si emite una cadena que contiene caracteres especiales y
olvida escaparlos, puede tener una vulnerabilidad XSS. En web2py las
cadenas son escapadas automáticamente evitando la vulnerabilidad.
- En PHP siempre comienza codificando al escribir HTML. En web2py ese
es el último paso. Comienza a codificar al diseñar sus tablas (esto le da
una interfaz web administrativa para recorrer sus datos). Prosigue al
crear Controladores (en python) los cuales describen cual página compone
su aplicación, que formulario es mostrado, y como se supone que el
usuario navegue las páginas. En este punto la aplicación esta funcionando
sin escribir ningún html. Agrega el html como último paso para asegurarse
que las páginas luzcan como ud. quiera.
Sobre el flujo de trabajo, Controladores web2py y FORMs
-------------------------------------------------------
En PHP ud. crea una página para mostrar un formulario y una página separada
para procesarlo. En web2py nunca hace esto. Los Formularios son objetos
(variables locales n las funciones de Controlador) que saben como procesarse
a si mismas, serializarse en html, validar las variables de entrada, generar
mensajes de error y eventualmente redireccionar a una página diferente.
Ejemplo::
def index():
form=FORM(INPUT(_name="n"),INPUT(_type="submit"))
if form.accepts(request.vars):
session.n=form.vars.n
redirect('hola')
return dict(form=form)
def hello():
return dict(nombre=session.n)
y en la vista ``index.html``::
¿Cual es su nombre? {{=form}}
y en la vista ``hola.html``::
Hola {{=nombre}}
- Una vez aceptado el formulario enviado, el controlador almacena el
nombre de usario en una variable de sesión (n), luego 'index'
redirecciona a la página 'hola'. web2py se encarga por ud. de las
sesiones, cookies, etc. transparentemente.
- Además, en la mayoría de los casos no es necesario crear los FORMs
dado que web2py automáticamente creara los formularios para
insertar/actualizar/eliminar registros en la base de datos (para todas
sus tablas) que ud. puede poner en sus páginas.
El Mapeador Objeto Relacional y los Modelos de web2py
-----------------------------------------------------
En PHP si ud. necesita acceder a la base de datos entonces debe hacer:
- crear la tabla fuera de PHP
- insertar las consultas SQL dentro del HTML vía el API propuesto por
PHP
- gestionar la base de datos usando herramientas de terceros
En web2py en cambio:
- ud. define sus tables en un modelo, si no existen son creadas por
web2py, si existen pero difieren, son alteradas
- ud. construye las consultas usando la DAL (ORM) la cual es una capa
de abstracción sobre la base de datos y su código que funcionará sin
problemas sobre sqlite, mysql, postgresql, oracle y (con algunas
limitaciones) en big table de Google.
- web2py crea una interfaz administrativa de la base de datos para su
aplicación que cambia dinámicamente al mismo tiempo que se alteran las
tablas. Puede usar esta interfaz para hacer la mayoría de las tareas de
mantenimiento.
Por ejemplo si ud. crea un archivo del Modelo llamado ``db.py``::
db=DAL('sqlite://prueba.db')
db.define_table('grito',Field('mensaje'))
web2py crea la base de datos sqlite y crea la tabla llamada 'grito' con un
campo llamado 'mensaje' del tipo char() (y un campo auto incremental oculto
llamado id). Puede practicar usando nuestro `diseñador sql`_
Luego ud. crea un Controlador, por ejemplo:::
def index():
db.grito.mensaje.requires=IS_NOT_EMPTY()
form=SQLFORM(db.grito)
if form.accepts(request.vars): response.flash='mensaje
enviado'
filas=db().select(db.grito.ALL)
return dict(form=form,filas=filas)
Este código completo hace una página que muestra el formulario, no permite
envíos vacios, y lista todos los mensajes mandados previamente. Esta función
acepta, construye el formulario, valida la entrada, agrega un mensaje de
error si corresponde, y al aceptar inserta el registro en la base de datos.
La función db().select(...) selecciona registros desde la base de datos.
Notar que el código de arriba funciona sin una vista pero podemos crearle una
llamada ``index.html``::
{{extend 'layout.html'}}
Mandar nuevo mensaje
{{=form}}
Mensajes previos
{{for fila in filas:}}
{{=fila.mensaje}}
{{pass}}
Falta los ``...`` ya que elegimos extender el ``layout.html.``
estándar de web2py El desarrollador puede facilmente crear layouts y
aplicarlos a las páginas al extenderlos. De esta manera se garantiza que
todas las páginas tengan una apariencia similar. Puede practicar usando el
`diseñador de layout`_.
Internacionalización
---------------------
En web2py:::
T('this is a message')
(y como es usual no necesita importar nada dado que se supone que use T)
web2py también puede hacer::
T('this is message %(name)s',dict(name='xxx'))
- En ambos casos la expresión es evaluada perezosamente cuando es
mostrada en las vistas.
- En web2py, la interfaz administrativa web provee una página de
interfaz de traducción.
- Para crear un archivo de lenguaje en web2py simplemente escribir su
nombre (por ejemplo ``es-ar.py`` ) en la interfaz administrativa.
¿Que más?
-----------
- web2py provee una interfaz administrativa web (no confundir con la
interfaz administrativa de la base de datos discutida arriba) que le
permite editar todos sus archivos, hacer varias tareas de mantenimiento,
compilar aplicaciones a bytecode, y empaquetarlas para su distribución.
De manera local o remota.
- si introduce un bug en su aplicación, tarde o temprano se manifestara
como una excepción que será lanzada. En este caso web2py emite un ticket
al visitante y registra una excepción, la traza y el código que la causó.
Puede recorrer estos tickets vía la intefaz administrativa web.
- web2py viene con su propio servidor capaz de SSL pero también
funciona con apache (``mod_proxy``, ``mod_rewrite``, y ``mod_wsgi``),
lighttpd (con fastcgi), y cualquier servidor que soporte CGI, FastCGI o
WSGI.
- web2py incluye bibliotecas para AJAX, JSON, REST, RSS, ATOM, RTF,
CSV, WIKI (markdown) y algunos protocolos más.
- web2py tiene ayudantes (como FORM e INPUT arriba) que ayuda a crear
objetos que pueden ser serializados en HTML o XML. Cualquier HTML/XML
correcto puede ser generado usando exclusivamente ayudantes (helpers).
- el código de web2py corre en la Google App Engine.
- web2py empaqueta todo lo que necesite en un archivo binario que ni
siquiera necesitará instalar. Mantengo el mio en una memoria USB.
Simplemente hace clic en el y este inicia el servidor web, la base de
datos sqlite y abre el navegador para acceso a la interfaz administrativa
web.
- web2py maneja los archivos estáticos por usted, los difunde (stream)
cuando son grandes (tanto al subirlos como al bajarlos),y automáticamente
soporta ``IF_MODIFIED_SINCE`` y ``PARTIAL CONTENT``. Puede hacer
streaming de audio y vidéo sin necesidad de herramientas externas o
configuraciones.
- web2py puede mapear URLs usando expresiones regulares por lo que
puede manejar URLs legadas.
- web2py no tiene archivos de configuración. Simplemente crea una
aplicación vía el interprete de comandos o la interfaz web y puede
crear/editar sus modelos, controladores y vistas (usando un editor de
textos o la interfaz administrativa web).
Hay un repositorio de `aplicaciones web2py libres`_ y un FAQ interactivo `FAQ
interactivo`_. (en inglés)
.. _from PHP to web2py: http://www.web2py.com/AlterEgo/default/show/106
.. _diseñador sql: http://mdp.cti.depaul.edu/sqldesigner
.. _diseñador de layout: http://mdp.cti.depaul.edu/layouts
.. _aplicaciones web2py libres: http://mdp.cti.depaul.edu/appliances
.. _FAQ interactivo: http://mdp.cti.depaul.edu/AlterEgo