menttes
 corporate training




                      Desarrollando aplicaciones web
                      con Zope 3




...
Que es Zope 3?
Zope 3 es un framework de aplicaciones web open source escrito en el lenguaje Python, 
especialmente apto p...
Quienes y cuando...



Inicialmente la tecnología Zope fue diseñada por la Zope Corporation. 


El desarrollo de Zope 3 co...
Propósitos de la plataforma



 ●
     Proveer un entorno de desarrollo atractivo para desarrolladores Python y otros 
   ...
Propósitos de la plataforma



 Facilitar el reuso del software
●


    ●
        Usando objetos externos a Zope
    ●
   ...
¿Esta Zope 3 listo para entornos de producción?


Zope 3 se usa en varios sitios de produccion de tamaño considerable. Alg...
menttes
menttes
menttes
Grok


Grok es Zope 3 simplificado.


Fue creado para acortar el tiempo que toma volverse productivo en Zope 3 y disminuye...
¿Que necesitamos saber?


Nos alcanza con conocer el lenguage de programación Python y un entendimento básico 
de programa...
Instalando Grok
Necesitaremos:


 Conexión a internet, ya que Grok se instala a traves de la red.
●


 Python 2.4 instalad...
Creando un proyecto


Un proyecto en Grok es un entorno de desarrollo completo.


    $ grokproject Sample



Esto creara ...
La instancia Zope

    $ cd Sample



Desde alli podemos levantar nuestra instancia Zope:


    $ parts/instance/bin/zopec...
menttes
http://localhost:8080/test

                             menttes
La aplicación
Las fuentes de nuestra aplicacion se encuentran en /src/sample :


    ..
    app.py
    app_templates
    c...
La aplicación


    import grok


    class Sample(grok.Application, grok.Container):
        pass


    class Index(grok....
El Template
En el directorio app_templates vamos a encontrar el template index.pt:


    <html>
    <head></head>
    <bod...
ZCML (Zope Configuration Markup Language)
Pondremos en el directorio de la aplicacion el archivo de configuración 
configu...
Agregando views (vistas)
Nuestro view se llama index. Esto significa que es la vista por defecto. Tambien puede ser 
acced...
Agregando views
Para decirle a Grok que use este template modificaremos app.py:


     import grok
  
     class Sample(gr...
Agregando views

Una vista (view) es una forma de ver un modelo, en este caso nuestra aplicación Sample. 

La definicion d...
Expresiones TAL



Los Zope Page Templates son documentos XHTML, lo que significa que pueden ser vistos 
y editados usando...
Template Attribute Language (TAL)

El Template Attribute Language (TAL) es un lenguaje expresado como atributos en las 
et...
Expresiones TAL
 ●
     path, describen una caminata desde un objeto hacia otro.


     “view/current_time”


 ●
     stri...
Comandos TAL

●
     define

●
     condition

●
     repeat

●
     content

●
     replace

●
     attributes

         ...
Propiedades de los Page Templates

El mecanismo de XML y HTML de Zope:



 ●
     conserva el template como código XML bie...
Haciendo páginas dinámicas
Usaremos directivas de Zope Page Templates (ZPT) para generar contenidos dinámicos. Cambiando 
...
Recursos estáticos para nuestras páginas

Usualmente necesitaremos referirnos a recursos en nuestras páginas, como imágene...
Recursos estáticos para nuestras páginas
Para usarlo, lo referimos desde index.pt:


         <html>
         <head>
     ...
Recursos estáticos para nuestras páginas

El código fuente se verá asi:


         <html>
             <link rel=quot;styl...
Usando métodos view
ZPT esta deliberadamente limitado en cuanto a lo que permite hacer con Python. Es una buena 
práctica ...
Usando métodos view

Integremos un poco de código en nuestro proyecto Grok. Modificando app.py:


    import grok
    from...
Usando métodos view

Hemos agregado un método que devuelve un string. Ahora mostremos este string en la 
página index.pt:
...
Usando métodos view


Una forma un poco mas corta y mas sencilla de leer a veces en ZPT es usando una 
expresion path:


 ...
Generando HTML desde Python
A veces se obtendra o generara HTML desde código Python para luego incluirlo en una 
página. P...
Generando HTML desde Python
Y cambiamos index.pt de la siguiente manera:


     <html>
     <body>
           <p tal:conte...
Views completamente dirijidas con Python
A veces es inconveniente usar templates. Tal vez ni siquiera estamos devolviendo ...
Configurando el content-type
Cuando se genera el contenido desde el view puede ser útil cambiarlo a otra cosa que no sea t...
Haciendo cálculos antes de ver una página
Podemos hacer que el view haga ciertos cálculos para nuestra página y asi hacer ...
Haciendo cálculos antes de ver una página



Necesitaremos un template index.pt que use alpha:


    <html>
    <body>
   ...
Leyendo parámetros URL


Usualmente cuando desarrollemos nuestra aplicación vamos a querer no solo mostrar 
datos, sino ta...
Leyendo parámetros URL


Modificamos app.py para que se vea asi:


    import grok


    class Sample(grok.Application, gr...
Leyendo parámetros URL

Necesitaremos un index.pt que use sum:


    <html>
    <body>
         <p tal:content=quot;python...
Leyendo parámetros URL


Sino pasamos parámetros por el URL (value1 y value2) obtendremos un error:


    A system error o...
Leyendo parámetros URL


Modificamos el codigo para que funcione aunque no preoveamos parámetros:


    import grok


    ...
Formularios simples
Usemos un formulario para pasar los parámetros. Cambiamos index.pt para que contenga 
un formulario co...
Formularios simples
<form tal:attributes=quot;action python:view.url()quot; method=quot;GETquot;>


Un detalle para notar ...
Formularios simples
Si los parámetros son string vacíos no podrán ser convertidos a enteros. Otra cosa poco 
simpática es ...
Modelos

Hemos visto como mostrar páginas web, ahora veremos un poco mas sobre lo 
que estamos mostrando: el modelo. El mo...
La vista para un modelo
La clase Sample es un grok.Container, asi que la usaremos para ver los principios básicos 
de mode...
La vista para un modelo
Si quisieramos ver esta informacion en nuestro template index.pt:


    <html>
    <body>
        ...
La vista para un modelo
Hagamos que la vista modifique la forma en que vemos la información (sin modificar los 
datos del ...
Almacenando datos




¿Que tal si quisieramos almacenar alguna información? Como algun dato ingresado por el 
usuario. La ...
Almacenando datos
Creemos una aplicación que almacene un tramo de texto. Usaremos una vista para visualizar el texto (inde...
Almacenando datos
Esto setea el atributo text en la instancia del objeto Sample en la base de datos, sobreescribiendo 
el ...
Template de edición
Creamos un template edit.pt con el siguiente contenido:


<html>
<body>
     <form tal:attributes=quot...
Redireccion
Cambiemos el formulario de edit para que redirija devuelta a la página de index luego de 
presionado el boton ...
Reglas de persistencia




 ●
     Para almacenar datos de una clase en la ZODB debemos hacerla subclase 
     de persiste...
Reglas de persistencia




 ●
     Para almacenar instancias éstas deben estar conectadas a otras clases 
     persistente...
Reglas de persistencia




 ●
     Para asegurarse que la ZODB se entere que se ha cambiado un objeto 
     mutable (como ...
Reglas de persistencia

Si se construye el contenido de la aplicación con subclases de  grok.Model y 
grok.Container práct...
Reglas de persistencia
       def addText(self, text):
         self.list.append(text)
               self._p_changed = Tr...
Reglas de persistencia

Modificamos index.pt para que muestre la lista:


    <html>
    <body>
         Se guardaron los ...
Asociando explícitamente una vista a un modelo



Como sabe Grok que una vista pertenece a un determinado modelo? En los e...
Asociando explícitamente una vista a un modelo

Sea la siguiente app.py:


     import grok
  
     class Sample(grok.Appl...
Contenedores




Un contenedor es un tipo especial de objeto modelo que puede contener otros objetos. La 
aplicación Sampl...
Contenedores




Desde la perspectiva Python, se puede pensar en contenedores como diccionarios. 
Permiten acceso por item...
Contenedores
Probemos un objeto de aplicación que tenga una página index donde se muestran sus 
contenidos. Se puede selec...
Contenedores

    class SampleIndex(grok.View):
        grok.context(Sample)
        grok.name('index')


        def upda...
Contenedores

    class EntryIndex(grok.View):
        grok.context(Entry)
        grok.name('index')



Hay otro detalle,...
Contenedores
Este es el template asociado con SampleIndex, sampleindex.pt:


     <html>
     <head>
     </head>
     <bo...
Contenedores


      <h2>Agregar nueva entrada</h2>
      <form tal:attributes=quot;action python:view.url()quot; method=q...
Contenedores
Finalmente, una página index para Entry. Tiene un template para mostrar el atributo text:


     <html>
     ...
menttes
Referencias

●
     www.zope.org 

●
     www.archive.org/details/grok_todo_part1

●
     grokzope.org

●
     worldcooker...
Upcoming SlideShare
Loading in...5
×

Desarrollando aplicaciones web con Zope 3

2,960

Published on

Charla de introducción a zope3: Qué es Zope 3 - Propositos de la plataforma, Aplicación, Qué es Grok, como desarrollar una aplicación con Grok, vistas, zcmls, expresiones tal, generando html desde python, formularios, almacenamiento de datos, contenedores,

Published in: Business, Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,960
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
109
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Desarrollando aplicaciones web con Zope 3

  1. 1. menttes corporate training Desarrollando aplicaciones web con Zope 3 Pablo Ambrosio pandres@menttes.com
  2. 2. Que es Zope 3? Zope 3 es un framework de aplicaciones web open source escrito en el lenguaje Python,  especialmente apto para desarrollar aplicaciones de manejo de contenido (content  management system), intranets, portales. Provee un arquitectura de componentes y una base de datos transaccional orientada a  objetos. El diseño de Zope 3 esta influenciado por practicas de desarrollo como programación ágil  y testeo automatizado. menttes
  3. 3. Quienes y cuando... Inicialmente la tecnología Zope fue diseñada por la Zope Corporation.  El desarrollo de Zope 3 comenzo a fines del 2001, y fue lanzado en Noviembre del 2004.  Basandose en la experiencia de Zope 2 fue totalmente reescrito, solo conservando su  base de datos ZODB. Es desarrollado por una comunidad libre donde la practica de Sprints es comun. En el 2006 se crea la Zope foundation para promover la plataforma y proveer soporte a la  comunidad. menttes
  4. 4. Propósitos de la plataforma ● Proveer un entorno de desarrollo atractivo para desarrolladores Python y otros  desarrolaldores ● Facilitar la creación de objetos utilizables en Zope: ● Posibilitando el uso de clases Python preexistentes ● Usando las prestaciones del framework en forma incremental y gradual ● Facilitar la curva de aprendizaje menttes
  5. 5. Propósitos de la plataforma  Facilitar el reuso del software ● ● Usando objetos externos a Zope ● Agregando, quitando o reemplazando funcionalidades de los objetos existentes. ● Proveyendo métodos alternativos de acceso a los objetos (FTP, XML­RPC)  Aplicando las lecciones aprendidas usando y construyendo Zope 2 ●  Proveyendo soporte para internacionalización y localización ●  Integrando patrones de diseño en Zope ● menttes
  6. 6. ¿Esta Zope 3 listo para entornos de producción? Zope 3 se usa en varios sitios de produccion de tamaño considerable. Algunas  aplicaciones públicas incluyen: ●  Launchpad ●  SchoolTool menttes
  7. 7. menttes
  8. 8. menttes
  9. 9. menttes
  10. 10. Grok Grok es Zope 3 simplificado. Fue creado para acortar el tiempo que toma volverse productivo en Zope 3 y disminuye las  lineas de código a escribir reemplazando los temidos archivos ZCML. Es un framework (si, otro). menttes
  11. 11. ¿Que necesitamos saber? Nos alcanza con conocer el lenguage de programación Python y un entendimento básico  de programación web (HTML, forms, URLs). Para ver como Grok nos puede ayudar a construir nuestra aplicación web, comenzaremos  con las cosas simples, para luego ir a hacia usos mas complejos. menttes
  12. 12. Instalando Grok Necesitaremos:  Conexión a internet, ya que Grok se instala a traves de la red. ●  Python 2.4 instalado. ● Como grok utiliza código fuente de Zope 3 para su distribución:  Python quot;devquot; package. ●  Compilador C (tipicamente gcc) instalado. ●  easy_install, para poder trabajar con “eggs”. ● Listo? $ sudo easy_install grokproject menttes
  13. 13. Creando un proyecto Un proyecto en Grok es un entorno de desarrollo completo. $ grokproject Sample Esto creara un nuevo subdirectorio llamado “Sample”, e instalará el proyecto allí.  grokproyect automáticamente baja e instala Zope 3 y Grok dentro del directorio.  Luego de proveer el nombre del módulo, al que llamaremos “app.py” (provisto por defecto)  y un nombre de usuario y password inicial, estamos listos para comenzar. menttes
  14. 14. La instancia Zope $ cd Sample Desde alli podemos levantar nuestra instancia Zope: $ parts/instance/bin/zopectl fg Zope 3 estara disponible en el puerto 8080, nos logeamos ingresando el usuario y  contraseña ya indicados: http://localhost:8080 menttes
  15. 15. menttes
  16. 16. http://localhost:8080/test menttes
  17. 17. La aplicación Las fuentes de nuestra aplicacion se encuentran en /src/sample : .. app.py app_templates configure.zcml __init__.py README.txt static Grok sabe como asociar el directorio con el módulo según el nombre. Veamos el código de nuestra aplicación, app.py. menttes
  18. 18. La aplicación import grok class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     pass # see app_templates/index.pt Suficiente para mostrar la página de bienvenida. menttes
  19. 19. El Template En el directorio app_templates vamos a encontrar el template index.pt: <html> <head></head> <body>   <h1>Congratulations!</h1>   <p>Your Grok application is up and running.   Edit <code>sample/app_templates/index.pt</code> to change   this page.</p> </body> Esta es nuestra página de bienvenida. http://localhost:8080/test menttes
  20. 20. ZCML (Zope Configuration Markup Language) Pondremos en el directorio de la aplicacion el archivo de configuración  configure.zcml. A diferencia de otras aplicaciones Zope 3, este solo contiene una  línea que cumple la función de registrar la aplicación. Podemos ignorar este archivo durante el desarrollo, grok se encarga de hacer la  configuración por nosotros <grok package=quot;.quot; xmlns=quot;http://namespaces.zope.org/grokquot; /> menttes
  21. 21. Agregando views (vistas) Nuestro view se llama index. Esto significa que es la vista por defecto. Tambien puede ser  accedida explicitamente:     http://localhost:8080/test/index Creamos un segundo template llamado bye.pt en app_templates con el siguiente  contenido: <html> <body> <p>Chau mundo...</p> </body> </html> menttes
  22. 22. Agregando views Para decirle a Grok que use este template modificaremos app.py: import grok    class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     pass class Bye(grok.View):     pass menttes
  23. 23. Agregando views Una vista (view) es una forma de ver un modelo, en este caso nuestra aplicación Sample.  La definicion de clase vacía es suficiente para que Grok busque en app_templates por  bye.pt. La regla es que un template debe tener el mismo nombre que su clase asociada, con  minúsculas:     http://localhost:8080/test/bye Los URL en Zope son case sensitive. En este punto habrá que reiniciar Zope. menttes
  24. 24. Expresiones TAL Los Zope Page Templates son documentos XHTML, lo que significa que pueden ser vistos  y editados usando herramientas compatibles con XHTML. ZPT (Zope Page Templates) esta basado en los lenguajes TAL (Template Attribute  Language) y METAL (Macro Expansion Template Attribute Language), ambos son  específicos de Zope.  Existen varias implementaciones en Python y en otros lenguajes. Puede ser usado con  otras aplicaciones. menttes
  25. 25. Template Attribute Language (TAL) El Template Attribute Language (TAL) es un lenguaje expresado como atributos en las  etiquetas (tags) HTML. Las etiquetas tienen la forma: <p tal:comando=quot;expresionquot;>Texto</p> Todas las declaraciones en TAL consisten de atributos en etiquetas cuyos nombres  comienzan con “tal:” , y todas tienen valores asociados, que siempre van entre comillas. Estas etiquetas son código HTML válido, o sea que estos documentos se pueden editar  con cualquier editor de HTML. menttes
  26. 26. Expresiones TAL ● path, describen una caminata desde un objeto hacia otro. “view/current_time” ● string, permiten combinar fácilmente expresiones path y texto quot;string:La fecha es ${view/current_time}.quot; ● python, puede contener cualquier cosa que el lenguaje Python  considere una  expresión. No se pueden usar declaraciones como if o while. “python:year != 2005” ● otras... (Exists, Not) menttes
  27. 27. Comandos TAL ●  define ●  condition ●  repeat ●  content ●  replace ●  attributes menttes
  28. 28. Propiedades de los Page Templates El mecanismo de XML y HTML de Zope: ● conserva el template como código XML bien formado ● intenta ser no invasivo usando atributos registrados como   namespaces  (TAL)  ● provee soporte para macros (METAL) ● provee soporte de para internacionalización menttes
  29. 29. Haciendo páginas dinámicas Usaremos directivas de Zope Page Templates (ZPT) para generar contenidos dinámicos. Cambiando  index.pt: <html> <body> <p tal:content=quot;python: 1 + 1quot;>esto se reemplaza</p> </body> </html> El código fuente se verá así: <html> <body> <p>2</p> </body> </html> menttes
  30. 30. Recursos estáticos para nuestras páginas Usualmente necesitaremos referirnos a recursos en nuestras páginas, como imágenes,  archivos CSS y código Javascript. Como ejemplo agregemos un poco de estilo en nuestra  página Creamos un directorio nuevo llamado “static” en el “sample package” (src/sample/static).  Dentro creamos un archivo llamado style.css: body {     background­color: #FF0000; } menttes
  31. 31. Recursos estáticos para nuestras páginas Para usarlo, lo referimos desde index.pt: <html> <head> <link rel=quot;stylesheetquot; type=quot;text/cssquot;         tal:attributes=quot;href static/style.cssquot; /> </head> <body> <p>Hola mundo!</p> </body> </html> Notar el uso de la directiva tal:attributes. Usamos Zope Page Templates para generar  dinámicamente el enlace al archivo style.css. menttes
  32. 32. Recursos estáticos para nuestras páginas El código fuente se verá asi: <html> <link rel=quot;stylesheetquot; type=quot;text/cssquot;        href=quot;http://localhost:8080/test/@@/sample/style.cssquot; /> <body> <p>Hola mundo!</p> </body> </html> Igualmente poniendo los archivos de imágenes o los .js en el directorio “static” y creando  el URL a ellos usando static/<archivo> en el page template. menttes
  33. 33. Usando métodos view ZPT esta deliberadamente limitado en cuanto a lo que permite hacer con Python. Es una buena  práctica de diseño hacer cualquier cosa que sea un poco mas complicada con código Python. Usar código Python arbitrariamente desde ZPT es fácil, agregamos métodos a la clase view y los  usamos desde el template. Si quisieramos mostrar la fecha actual... >>> from datetime import datetime esta declaración esta fuera de las capacidades de los ZPT, no esta permitido importar módulos  dentro de un template. menttes
  34. 34. Usando métodos view Integremos un poco de código en nuestro proyecto Grok. Modificando app.py: import grok from datetime import datetime class Sample(grok.Application, grok.Container):     pass class Index(grok.View):         def current_datetime(self):         now = datetime.now()         return now.strftime('%Y­%m­%d %H:%M') menttes
  35. 35. Usando métodos view Hemos agregado un método que devuelve un string. Ahora mostremos este string en la  página index.pt: <html> <body> <p tal:content=quot;python:view.current_datetime()quot;>Hola</p> </body> </html> veremos algo como: 2007­02­27 17:21 menttes
  36. 36. Usando métodos view Una forma un poco mas corta y mas sencilla de leer a veces en ZPT es usando una  expresion path: <html> <body> <p tal:content=quot;view/current_datetimequot;></p> </body> </html> Corriendo esto se obtiene el mismo resultado que en el caso anterior. menttes
  37. 37. Generando HTML desde Python A veces se obtendra o generara HTML desde código Python para luego incluirlo en una  página. Por razones de seguridad contra cross­scripting TAL automaticamente escapa  HTML &gt; y &lt;. Con la directiva “structure” se le puede decir explícitamente a TAL que  no escape HTML, asi se puede pasara literalmente al template: import grok    class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     def some_html(self):         return quot;<b>YO GROK BOLD</b>quot; menttes
  38. 38. Generando HTML desde Python Y cambiamos index.pt de la siguiente manera: <html> <body> <p tal:content=quot;structure python:view.some_html()quot;></p> </body> </html> veremos el texo: YO GROK BOLD el HTML generado fue integrado en la página. Sin la directiva “structure” se vería algo como: <b>YO GROK BOLD</b> menttes
  39. 39. Views completamente dirijidas con Python A veces es inconveniente usar templates. Tal vez ni siquiera estamos devolviendo una página  HTML. En estos casos se peude usar el método render en la view: import grok    class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     def render(self):         return quot;YO GROK SIN TEMPLATEquot; En este caso queda el template index.pt dando vueltas, ante la ambiguedad Grok se niega a  adivinar, luego habra que remover el template. menttes
  40. 40. Configurando el content-type Cuando se genera el contenido desde el view puede ser útil cambiarlo a otra cosa que no sea text/plain: import grok    class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     def render(self):         self.response.setHeader('Content­Type',                                  'text/xml; charset=UTF­8')         return quot;<doc>Un poco de XML</doc>quot; Todas las vistas en Grok tienen la propiedad “response” que se puede usar para manipular los headers de  respuesta. menttes
  41. 41. Haciendo cálculos antes de ver una página Podemos hacer que el view haga ciertos cálculos para nuestra página y asi hacer el cálculo una vez por  recarga (aunque usemos el valor múltiples veces en la página). Esto se puede hacer usando el método update en la clase de la vista: import grok class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     def update(self):         self.alpha = 2 ** 8 Esto setea “alpha” en la vista justo antes de que se muestre el template.  menttes
  42. 42. Haciendo cálculos antes de ver una página Necesitaremos un template index.pt que use alpha: <html> <body> <p tal:content=quot;python:view.alphaquot;>resultado</p> </body> </html> menttes
  43. 43. Leyendo parámetros URL Usualmente cuando desarrollemos nuestra aplicación vamos a querer no solo mostrar  datos, sino tambien recibirlos (y procesarlos). Una forma simple de hacer esto es  obteniendo la informacion como parámetros en un URL.  Hagamos una aplìcacion que resuelva sumas. Si le pasamos el siguiente URL a la  aplicación:     http://localhost:8080/test?value1=3&value2=5 deberíamos obtener su suma (8) como resultado en la página. menttes
  44. 44. Leyendo parámetros URL Modificamos app.py para que se vea asi: import grok class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     def update(self, value1, value2):         self.sum = int(value1) + int(value2) menttes
  45. 45. Leyendo parámetros URL Necesitaremos un index.pt que use sum: <html> <body> <p tal:content=quot;python:view.sumquot;>suma</p> </body> </html> Otras sumas funcionaran por supuesto:     http://localhost:8080/test?value1=50&value2=50 menttes
  46. 46. Leyendo parámetros URL Sino pasamos parámetros por el URL (value1 y value2) obtendremos un error: A system error occurred. En el traceback donde corremos el Zope veremos: TypeError: Missing argument to update(): value1 Este es el mensaje de error relevante. menttes
  47. 47. Leyendo parámetros URL Modificamos el codigo para que funcione aunque no preoveamos parámetros: import grok class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     def update(self, value1=0, value2=0):         self.sum = int(value1) + int(value2) menttes
  48. 48. Formularios simples Usemos un formulario para pasar los parámetros. Cambiamos index.pt para que contenga  un formulario como: <html> <body> <form tal:attributes=quot;action python:view.url()quot; method=quot;GETquot;>   Valor 1: <input type=quot;textquot; name=quot;value1quot; value=quot;quot; /><br />   Valor 2: <input type=quot;textquot; name=quot;value2quot; value=quot;quot; /><br />   <input type=quot;submitquot; value=quot;Sumar!quot; /> </form> <p>La suma es: <span tal:replace=quot;python:view.sumquot;>suma</span> </p> </body> </html> menttes
  49. 49. Formularios simples <form tal:attributes=quot;action python:view.url()quot; method=quot;GETquot;> Un detalle para notar en este código es que generamos la acción del formularion  dinámicamente. Básicamente le decimos al formulario que se reenvíe a si mismo. El  método url, propio de Grok, nos permite obtener el URL de la misma vista (y otros URLs  tambien). Todavía tenemos algunos problemas con ese código. Si no cargamos parámetros y  enviamos el formulario obtendremos un error como el siguiente: File quot;../app.pyquot;, line 8, in update   self.sum = int(value1) + int(value2) ValueError: invalid literal for int(): menttes
  50. 50. Formularios simples Si los parámetros son string vacíos no podrán ser convertidos a enteros. Otra cosa poco  simpática es que mostramos una suma (0) aun cuando no proveeemos datos: class Index(grok.View):     def update(self, value1=None, value2=None):         try:             value1 = int(value1)             value2 = int(value2)         except (TypeError, ValueError):             self.sum = quot;No hay sumaquot;             return         self.sum = value1 + value2 En Grok uno puede usar las bibliotecas schema y formlib de Zope 3 para automatizar la  generacion de formularios. menttes
  51. 51. Modelos Hemos visto como mostrar páginas web, ahora veremos un poco mas sobre lo  que estamos mostrando: el modelo. El modelo contiene la lógica de la aplicación,  independientemente de la vista. La vista, junto con el template, es responsable de mostrar la información y su  interfaz de usuario. El modelo representa la información (o contenido) de los que  trata la aplicación , como documentos, entradas de blog o páginas wiki. El  modelo no debe saber nada sobre como son mostrados los datos.  En una aplicacion Grok, los modelos se definen como subclases de grok.Model o  grok.Container.  menttes
  52. 52. La vista para un modelo La clase Sample es un grok.Container, asi que la usaremos para ver los principios básicos  de modelos. Modifiquemos app.py para que tenga información disponible: import grok class Sample(grok.Application, grok.Container):     def information(self):         return quot;Esta es informacion del modeloquot; class Index(grok.View):     pass En este caso, la información esta hardcodeada, pero podemos imaginar que la estamos  extrayendo de algun otro lado, como una base de datos o el file system. menttes
  53. 53. La vista para un modelo Si quisieramos ver esta informacion en nuestro template index.pt: <html> <body> <p tal:content=quot;python:context.information()quot;>reemplazado</p> </body> </html> Vimos que se pueden acceder métodos y atributos de una vista usando la palabra clave  view en un template. De la misma manera la palabra context esta disponible en cada template, y nos permite  acceder informacion en el objeto contextual que la vista esta mostrando. En este caso una  instancia de Sample. menttes
  54. 54. La vista para un modelo Hagamos que la vista modifique la forma en que vemos la información (sin modificar los  datos del modelo claro). Cambiemos app.py: import grok class Sample(grok.Application, grok.Container):     def information(self):          return quot;Esta es información del modeloquot; class Index(grok.View):     def reversed_information(self):         return ''.join(reversed(self.context.information())) El objeto context tambien puede ser accedido desde la clase de la vista. menttes
  55. 55. Almacenando datos ¿Que tal si quisieramos almacenar alguna información? Como algun dato ingresado por el  usuario. La forma mas sencilla de hacer esto con Zope es usando la Zope Object  DataBase (ZODB). La ZODB es una base de datos de objetos Python. Se puede almacenar cualquier objeto  Python en ella siempre que se sigan algunas simples reglas (las “Reglas de Persistencia”).  Nuestro objeto de aplicacion Sample está almacenado en la base de datos, luego  podemos almacenar información en él. menttes
  56. 56. Almacenando datos Creemos una aplicación que almacene un tramo de texto. Usaremos una vista para visualizar el texto (index)  y otra para editarlo (edit). Esta es app.py: import grok class Sample(grok.Application, grok.Container):     text = 'texto por defecto' class Index(grok.View):     pass class Edit(grok.View):     def update(self, text=None):         if text is None:             return         self.context.text = text menttes
  57. 57. Almacenando datos Esto setea el atributo text en la instancia del objeto Sample en la base de datos, sobreescribiendo  el texto por defecto de la clase. Cambiamos el template index.pt para que se lea: <html> <body> <p>El texto: <span tal:replace=quot;python:context.textquot;>texto</span> </p> <p><a tal:attributes=quot;href python:view.url('edit')quot;>Edit this page</a> </p> </body> </html> Dándole al método url un string como argumento generará un URL a la vista llamada como el  string en el mismo objeto (test), en este caso test/edit. menttes
  58. 58. Template de edición Creamos un template edit.pt con el siguiente contenido: <html> <body> <form tal:attributes=quot;action view/urlquot; method=quot;POSTquot;> Texto a guardar: <input type=quot;textquot; name=quot;textquot; value=quot;quot; /><br /> <input type=quot;submitquot; value=quot;Storequot; /> </form> </body> </html> La página se reenvía a si misma y se verá el texto ingresado. Esto significa que el texto esta almacenado en  la base de datos. http://localhost:8080/test Se puede reiniciar Zope y volver a la página index y se verá que los cambios persisten. menttes
  59. 59. Redireccion Cambiemos el formulario de edit para que redirija devuelta a la página de index luego de  presionado el boton submit: class Edit(grok.View):     def update(self, text=None):         if text is None:             return         self.context.text = text         self.redirect(self.url('index')) La última línea es la nueva. Usamos el método url en la vista para construir el URL de la página  index. Dado que estamos en un template, podemos llamar el método sobre self. Luego se lo  pasamos a otro método disponible en todas las subclases de grok.View, redirect. menttes
  60. 60. Reglas de persistencia ● Para almacenar datos de una clase en la ZODB debemos hacerla subclase  de persistent.Persistent. La forma mas sencilla de hacer esto con Grok es  hacerla subclase de grok.Model o grok.Container. menttes
  61. 61. Reglas de persistencia ● Para almacenar instancias éstas deben estar conectadas a otras clases  persistentes que ya esten almacenadas. La forma mas simple con Grok es  agregarlas de alguna forma al objeto grok.Application, directa o  indirectamente. Esto se hace seteandolas como un atributo o poniéndolas en  un contenedor (si hacemos la aplicacion subclase de grok.Container). menttes
  62. 62. Reglas de persistencia ● Para asegurarse que la ZODB se entere que se ha cambiado un objeto  mutable (como una lista o diccionario Python) en una instancia, se setea el  atributo _p_changed en esa instancia a True. Esto solo es necesario cuando  el atributo no es persistente por si mismo. Tampoco es necesario cuando se  crea o sobreescribe un atributo directamente usando =. menttes
  63. 63. Reglas de persistencia Si se construye el contenido de la aplicación con subclases de  grok.Model y  grok.Container prácticamente se siguen todas las reglas. Si usamos un objeto mutable como una lista o un diccionario para almacenar datos  necesitamos tomar una acción especial. Modificando el código anterior para usar una lista: class Sample(grok.Application, grok.Container):     def __init__(self):         super(Sample, self).__init__()         self.list = [] menttes
  64. 64. Reglas de persistencia def addText(self, text):          self.list.append(text)         self._p_changed = True          class Edit(grok.View):     def update(self, text=None):         if text is None:             return         self.context.addText(text)         self.redirect(self.url('index')) Creamos un método addText en el modelo que se encarga de actualizar la lista e informar a la ZODB de  esto. Asi cualquier código de vista puede usar la API de Sample sin preocuparse por las reglas de  persistencia, ya que es una responsabilidad del modelo. menttes
  65. 65. Reglas de persistencia Modificamos index.pt para que muestre la lista: <html> <body> Se guardaron los textos: <ul>   <li tal:repeat=quot;text python:context.listquot; tal:content=quot;textquot;></li> </ul> <a tal:attributes=quot;href python:view.url('edit')quot;> Agregar un texto</a> </body> </html> menttes
  66. 66. Asociando explícitamente una vista a un modelo Como sabe Grok que una vista pertenece a un determinado modelo? En los ejemplos  vistos Grok hace esta asociacion automáticamente. Esto se pudo hacer porque solo hay  un modelo definido en el módulo (Sample). Detras de escena Grok hizo al modelo ser el  context de todas las vistas. Todo lo que Grok hace implícitamente también se puede hacer explícitamente. Esto es útil  cuando se necesite decirle a Grok que hacer, sobreescribiendo el comportamienteo por  defecto. Para asociar una vista con un modelo se usa la anotacion de clase grok.context. Una anotacion de clase es una forma declarativa de decirle a Grok algo acerca de una  clase Python. menttes
  67. 67. Asociando explícitamente una vista a un modelo Sea la siguiente app.py: import grok    class Sample(grok.Application, grok.Container):     pass class Index(grok.View):     grok.context(Sample) class Bye(grok.View):     grok.context(Sample) Lo único hecho es poner explícita la relación entre el modelo y la vista, usando la directiva grok.context. menttes
  68. 68. Contenedores Un contenedor es un tipo especial de objeto modelo que puede contener otros objetos. La  aplicación Sample es un contenedor, al ser subclase de grok.Container.  Una aplicación Grok está típicamete compuesta por contenedores y modelos. Con  modelos siendo contenidos en dichos contenedores. A su vez los modelos contenidos  tambien pueden ser contenedores, ya que estos son a su vez modelos. menttes
  69. 69. Contenedores Desde la perspectiva Python, se puede pensar en contenedores como diccionarios.  Permiten acceso por item (container['key']) para obtener sus contenidos. Tambien definen  métodos como keys() y values(). Los contenedores ademas proveen otras funcionalidades propias. Son persistentes, y  cuando son modificados no es necesario usar el atributo _p_changed. Tambien  implementan eventos especiales que pueden ser escuchados cuando nuevos items son  agregados en los contenedores o removidos. menttes
  70. 70. Contenedores Probemos un objeto de aplicación que tenga una página index donde se muestran sus  contenidos. Se puede seleccionar un item del contenido para verlo. Bajo la lista habrá un  formulario que premita agregar nuevo contenido. Este será app.py: import grok class Sample(grok.Application, grok.Container):     pass class Entry(grok.Model):     def __init__(self, text):         self.text = text Hemos creado un objeto que no es de aplicación, Entry. Es sólo un grok.Model. Necesita ser  creado con un texto como argumento al cual almacena. menttes
  71. 71. Contenedores class SampleIndex(grok.View):     grok.context(Sample)     grok.name('index')     def update(self, name=None, text=None):         if name is None or text is None:             return         self.context[name] = Entry(text) Luego siguen las vistas. Habra una para el contenedor Sample. Cuando su update es llamado  con dos valores, name y text, creara una nueva instancia de Entry con el texto dado, y la pondra  en el contenedor con el nombre name. Se usa la notacion tipo diccionario para agregar la nueva  Entry en el contenedor. menttes
  72. 72. Contenedores class EntryIndex(grok.View):     grok.context(Entry)     grok.name('index') Hay otro detalle, la idea es que estas vistas sean de tipo index. Esto no se puede deducir  automáticamente por el nombre de las clases, sin embargo, si lo dejamos solo Grok  hubiese llamado a las vistas sampleindex y entryindex. Para este caso existe otra anotacion de clase que puede ayudar, grok.name. Se puede  usar en ambas clases (grok.name('index')) para decirle explícitamente a Grok lo que  queremos. menttes
  73. 73. Contenedores Este es el template asociado con SampleIndex, sampleindex.pt: <html> <head> </head> <body>   <h2>Entradas existentes</h2>   <ul>     <li tal:repeat=quot;key python:context.keys()quot;>       <a tal:attributes=quot;href python:view.url(key)quot;           tal:content=quot;python:keyquot;></a>     </li>   </ul> Usamos keys() para obtener la lista de todos los nombres de los items en el contenedor. Creamos un link a  los items usando view.url(). menttes
  74. 74. Contenedores   <h2>Agregar nueva entrada</h2>   <form tal:attributes=quot;action python:view.url()quot; method=quot;POSTquot;>     Nombre: <input type=quot;textquot; name=quot;namequot; value=quot;quot; /><br />     Texto: <input type=quot;textquot; name=quot;textquot; value=quot;quot; /><br />     <input type=quot;submitquot; value=quot;Agregar entradaquot; />   </form> </body> En esta sección se muesta un formulario que envía los datos a la propia página index.  Tiene dos campos, name y text, que son manejados por update(). menttes
  75. 75. Contenedores Finalmente, una página index para Entry. Tiene un template para mostrar el atributo text: <html> <head> </head> <body>   <h2>Entrada <span tal:replace=quot;python:context.__name__quot;> </span>         </h2>   <p tal:content=quot;python:context.textquot;></p> </body>       </html> Reiniciamos Zope y probamos la aplicación. menttes
  76. 76. menttes
  77. 77. Referencias ●  www.zope.org  ●  www.archive.org/details/grok_todo_part1 ●  grokzope.org ●  worldcookery.com ●  wiki.zope.org/zope3 ●  www.zope.org/Documentation/Books/ZopeBook/2_6Edition/ZPT.stx ●  www.zope.com ●  www.schooltool.org ●  launchpad.net  paleosoft.org  foundation.zope.org menttes
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×