Desarrollando aplicaciones web con Zope 3

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    2 Favorites

    Desarrollando aplicaciones web con Zope 3 - Presentation Transcript

    1. menttes corporate training Desarrollando aplicaciones web con Zope 3 Pablo Ambrosio pandres@menttes.com
    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. 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. 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. 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. ¿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. menttes
    8. menttes
    9. menttes
    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. ¿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. 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 \"dev\" package. ●  Compilador C (tipicamente gcc) instalado. ●  easy_install, para poder trabajar con “eggs”. ● Listo? $ sudo easy_install grokproject menttes
    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. 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. menttes
    16. http://localhost:8080/test menttes
    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. 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. 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. 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=\".\" xmlns=\"http://namespaces.zope.org/grok\" /> menttes
    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. 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. 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. 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. 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=\"expresion\">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. Expresiones TAL ● path, describen una caminata desde un objeto hacia otro. “view/current_time” ● string, permiten combinar fácilmente expresiones path y texto \"string:La fecha es ${view/current_time}.\" ● 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. Comandos TAL ●  define ●  condition ●  repeat ●  content ●  replace ●  attributes menttes
    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. 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=\"python: 1 + 1\">esto se reemplaza</p> </body> </html> El código fuente se verá así: <html> <body> <p>2</p> </body> </html> menttes
    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. Recursos estáticos para nuestras páginas Para usarlo, lo referimos desde index.pt: <html> <head> <link rel=\"stylesheet\" type=\"text/css\"         tal:attributes=\"href static/style.css\" /> </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. Recursos estáticos para nuestras páginas El código fuente se verá asi: <html> <link rel=\"stylesheet\" type=\"text/css\"        href=\"http://localhost:8080/test/@@/sample/style.css\" /> <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. 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. 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. 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=\"python:view.current_datetime()\">Hola</p> </body> </html> veremos algo como: 2007­02­27 17:21 menttes
    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=\"view/current_datetime\"></p> </body> </html> Corriendo esto se obtiene el mismo resultado que en el caso anterior. menttes
    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 \"<b>YO GROK BOLD</b>\" menttes
    38. Generando HTML desde Python Y cambiamos index.pt de la siguiente manera: <html> <body> <p tal:content=\"structure python:view.some_html()\"></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. 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 \"YO GROK SIN TEMPLATE\" 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. 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 \"<doc>Un poco de XML</doc>\" Todas las vistas en Grok tienen la propiedad “response” que se puede usar para manipular los headers de  respuesta. menttes
    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. Haciendo cálculos antes de ver una página Necesitaremos un template index.pt que use alpha: <html> <body> <p tal:content=\"python:view.alpha\">resultado</p> </body> </html> menttes
    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. 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. Leyendo parámetros URL Necesitaremos un index.pt que use sum: <html> <body> <p tal:content=\"python:view.sum\">suma</p> </body> </html> Otras sumas funcionaran por supuesto:     http://localhost:8080/test?value1=50&value2=50 menttes
    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. 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. Formularios simples Usemos un formulario para pasar los parámetros. Cambiamos index.pt para que contenga  un formulario como: <html> <body> <form tal:attributes=\"action python:view.url()\" method=\"GET\">   Valor 1: <input type=\"text\" name=\"value1\" value=\"\" /><br />   Valor 2: <input type=\"text\" name=\"value2\" value=\"\" /><br />   <input type=\"submit\" value=\"Sumar!\" /> </form> <p>La suma es: <span tal:replace=\"python:view.sum\">suma</span> </p> </body> </html> menttes
    49. Formularios simples <form tal:attributes=\"action python:view.url()\" method=\"GET\"> 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 \"../app.py\", line 8, in update   self.sum = int(value1) + int(value2) ValueError: invalid literal for int(): menttes
    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 = \"No hay suma\"             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. 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. 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 \"Esta es informacion del modelo\" 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. La vista para un modelo Si quisieramos ver esta informacion en nuestro template index.pt: <html> <body> <p tal:content=\"python:context.information()\">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. 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 \"Esta es información del modelo\" 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. 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. 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. 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=\"python:context.text\">texto</span> </p> <p><a tal:attributes=\"href python:view.url('edit')\">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. Template de edición Creamos un template edit.pt con el siguiente contenido: <html> <body> <form tal:attributes=\"action view/url\" method=\"POST\"> Texto a guardar: <input type=\"text\" name=\"text\" value=\"\" /><br /> <input type=\"submit\" value=\"Store\" /> </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. 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. 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. 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. 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. 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. 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. Reglas de persistencia Modificamos index.pt para que muestre la lista: <html> <body> Se guardaron los textos: <ul>   <li tal:repeat=\"text python:context.list\" tal:content=\"text\"></li> </ul> <a tal:attributes=\"href python:view.url('edit')\"> Agregar un texto</a> </body> </html> menttes
    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. 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. 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. 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. 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. 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. 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. Contenedores Este es el template asociado con SampleIndex, sampleindex.pt: <html> <head> </head> <body>   <h2>Entradas existentes</h2>   <ul>     <li tal:repeat=\"key python:context.keys()\">       <a tal:attributes=\"href python:view.url(key)\"           tal:content=\"python:key\"></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. Contenedores   <h2>Agregar nueva entrada</h2>   <form tal:attributes=\"action python:view.url()\" method=\"POST\">     Nombre: <input type=\"text\" name=\"name\" value=\"\" /><br />     Texto: <input type=\"text\" name=\"text\" value=\"\" /><br />     <input type=\"submit\" value=\"Agregar entrada\" />   </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. 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=\"python:context.__name__\"> </span>         </h2>   <p tal:content=\"python:context.text\"></p> </body>       </html> Reiniciamos Zope y probamos la aplicación. menttes
    76. menttes
    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

    + r0verr0ver, 2 years ago

    custom

    1807 views, 2 favs, 1 embeds more stats

    Charla de introducción a zope3: Qué es Zope 3 - P more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 1807
      • 1765 on SlideShare
      • 42 from embeds
    • Comments 0
    • Favorites 2
    • Downloads 67
    Most viewed embeds
    • 42 views on http://labs.menttes.com

    more

    All embeds
    • 42 views on http://labs.menttes.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories