*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