formulários para plone: um passeio pelo framework z3c.form

25
Formul´ arios para Plone: um passeio pelo framework z3c.form Rud´ a Porto Filgueiras - [email protected] - @rudaporto September 29, 2011

Upload: ruda-filgueiras

Post on 09-Jul-2015

1.141 views

Category:

Technology


2 download

DESCRIPTION

Todo desenvolvedor web sabe o trabalho que dá desenvolver formulários de qualidade para suas aplicações. Por esse motivo, praticamente todos os frameworks web fornecem algum tipo de geração de formulários automáticos e/ou componentes para faciltar a criação de formulários customizados.No caso do Plone (o framework) não é diferente e o framework Archetypes já incluia nativamente a geração de formulários para seus tipos de conteúdo. Porém, além de ser complicado para customizar e debugar, existiam claros limites no que se poderia realizar com eles.Durante o desenvolvimento do BlueBream Aplication Server (antigo Zope3), uma variedade de componentes foram desenvolvidos que hoje fazer parte do ZTK (Zope Tool Kit). Um desses componentes é o pacote zope.formlib, que justamente foi criado para possibilitar a criação automática de formulários para objetos de conteúdo (models) e também para definição de formulários customizados. Porém, apesar da grande melhoria, a customização do formulário, definição de novas widgets ainda não eram satisfatórios.Com base da experiência e problemas do zope.formlib, que surgiu em 2007 o framework z3c,form. Após anos de amadurecimento, hoje ele está totalmente integrado ao Plone e atualmente é considerado a melhor opção para a criação de formulários. O z3c.form possui um excelente nível de maturidade, cobertura de testes e mais importante: documentação detalhada e grande flexibilidade, sem que isso torne o torne tão complexo e difícil de se aprender.O objetivo dessa palestra e fornecer uma visão geral do framework e seus componentes, e realizar um passeio por exemplos de formulários desenvolvidos com z3c.form que demonstrem seus recursos e sua integração com Plone.

TRANSCRIPT

Page 1: Formulários para Plone: um passeio pelo framework z3c.form

Formularios para Plone: um passeio peloframework z3c.form

Ruda Porto Filgueiras - [email protected] - @rudaporto

September 29, 2011

Page 2: Formulários para Plone: um passeio pelo framework z3c.form

Agenda

Introducao

Historia

z3c.form

Perguntas

Page 3: Formulários para Plone: um passeio pelo framework z3c.form

Introducao

I Por que formularios sao importantes?

I Como posso simplificar a criacao de formularios?

I Como posso melhorar o reuso?

I Como os formularios podem ser mais resistentes a falhas?

Page 4: Formulários para Plone: um passeio pelo framework z3c.form

CMFFormController

Recursos:

I Cola que conecta scripts com formularios e vice-versa

I Simplifica a codificacao de formularios / scripts paramanipular formularios

I Gerencia a transicao entre formularios e scripts

I Conponentes: Forms (.cpt), Validators(.vpy),Actions(Buttoes), Scritps(.cpy), State

Problemas:

I Arquivos espalhados dificultam o entendimento do fluxo

I Criacao e exibicao de widgets nao sao tratadas

I Nao funciona com ZCA packages / views

Page 5: Formulários para Plone: um passeio pelo framework z3c.form

zope.formlib

Caracteristicas:

I pacote padrao do ZTK para criacao de formularios

I formularios sao um tipo de BrowserPage (context, request)

I define classes reusaveis para criacao de formularios

I possui template padrao (plone.app.form overrrides)

I permite a customizacao de widgets, actions, validators, etc

I define o padrao update() e render() ao ser invocado

Problemas:

I Nivel de customizacao e limitado para casos mais complexos

I Nao e pensado para a definicao de formularios aninhados (paie filho)

I Documentacao escassa: ”luke use de force: read the source”

Page 6: Formulários para Plone: um passeio pelo framework z3c.form

z3c.form

O objetivo geral do z3c.form e tornar o desenvolvimento deformularios o mais simples possıvel e ao mesmo tempo proverhooks que permitam a customizacao dos formularios em qualquernıvel de acordo com as necessidades reais de diferentes casos deuso. Principais componentes (modulos):

form formularios base: Form, AddForm, EditForm,DisplayForm

groups formularios compostos de grupos de campos(fieldsets)

subform formularios aninhados

field API para manipulalcao dos campos do formulario

button API para manipulacao dos botoes do formulario

validator API de validacao dos dados do formulario

widget API de criacao das widgets

action API para definicao e manipulacao de actions handlers

Page 7: Formulários para Plone: um passeio pelo framework z3c.form

z3c.form: processamento do formulario

Elementos principais:

self.request objeto representando a requiscao HTTP atual

self.context Item associado ao formulario de acordo com contextono qual ele foi invocado;

self.getContent() Objeto retirado do contexto e que seramanipulado pelo formulario a nao ser queignoreContext seja definido como True;

self.status A mensagem que sera exibida no topo da regiao doconteudo quando o formulario for renderizado.

updateWidgets atualiza todas as widgets de acordo com os dadosenviados

updateActions invoca os actions handlers do formulario de acordocom o botao pressionados

render invoca o template padrao que gera o HTML doformulario e retorna esse conteudo

Page 8: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: Person Interface

1 import zope . i n t e r f a c e2 import zope . schema34 c l a s s IPerson ( zope . i n t e r f a c e . I n t e r f a c e ) :56 i d = zope . schema . TextLine (7 t i t l e=u ' ID ' ,8 r e a don l y=True ,9 r e q u i r e d=True )

1011 name = zope . schema . TextLine (12 t i t l e=u 'Name ' ,13 r e q u i r e d=True )1415 gender = zope . schema . Cho ice (16 t i t l e=u ' Gender ' ,17 v a l u e s=( 'male ' , ' f ema l e ' ) ,18 r e q u i r e d=Fa l se )19 ...

Page 9: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: Person

1 from zope . schema . f i e l d p r o p e r t y import F i e l dP r o p e r t y23 c l a s s Person ( ob ject ) :4 zope . i n t e r f a c e . implements ( IPe r s on )56 i d = F i e l dP r o p e r t y ( IPe r s on [ ' i d ' ] )7 name = F i e l dP r o p e r t y ( IPe r s on [ 'name ' ] )8 gender = F i e l dP r o p e r t y ( IPe r s on [ ' gender ' ] )9

10 def i n i t ( s e l f , id , name , gender=None ) :11 s e l f . i d = i d12 s e l f . name = name13 i f gender :14 s e l f . gender = gender

Page 10: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: PersonAddForm

1 from z3c . form import form , f i e l d23 c l a s s PersonAddForm ( form . AddForm ) :45 f i e l d s = f i e l d . F i e l d s ( IPe r s on )67 def c reate ( s e l f , data ) :8 re tu rn Person (** data )9

10 def add ( s e l f , ob ject ) :11 s e l f . c on t e x t [ ob ject . i d ] = ob ject1213 def nextURL ( s e l f ) :14 re tu rn ' i n d e x . html '

Page 11: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: processamento do formulario

1 from z3c . form . t e s t i n g import TestRequest23 r e q u e s t = TestReques t ( )4 addForm = PersonAddForm ( app , r e q u e s t )5 addForm . update ( )

Nesse momento, ocorre uma seria de acoes:

I As widgets sao inicializadas de acordo com os camposdefinidos no atributo fields do formulario

I O atributo addForm.widgets e o widget manager que contemtodas as widgets inicializdas

I Porem nao sao criadas widgets para todos os campos: se odado nao estiver acessıvel no objeto ou um se houver umaconfiguracao para ignorar esse campo

Page 12: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: inicializacao das widgetsVarias informacoes dos campos sao transferidas para as widgets,mas podem ser alterados posteriormente:

1 addForm . w idge t s [ ' age ' ]23 # f i e l d . t i t l e −> age . l a b e l4 age . l a b e l5 u 'Age '

67 #f i e l d . r e q u i r e d −> age . r e q u i r e d8 age . r e q u i r e d9 Fa l se

O proximo passo e determinar o valor que deve ser exibido nawidget, na seguinte ordem:

I O valor padrao definido no schema

I O valor atual do objeto que esta sendo manipulado

I O valor armazenado no request, se o formulario ainda nao foisubmetido ou ocorreu erros na validacao

Page 13: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: propriedades das widgets

A propriedade mode define se a widget sera renderizada paraedicao (input) ou visualizacao (display):

1 age . mode2 ' i n pu t '

O modo da widget e inicializado seguindo a seguinte ordem (ositens posteriores sobrescrevem os anteriores):

I O valor global definido no widget manager

I A permissao do attributo do objeto que esta sendo manipulado

I A flag readonly definida no schema

I O atributo mode definido no field

Outras propriedades que podem ser customizadas na widget sao osatributos: label e required.

Page 14: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: encontrar um action manager e executa-lo

O botao ”Add” e ao mesmo tempo um action e um widget:

1 l en ( addForm . a c t i o n s )2 134 addAct ion = addForm . a c t i o n s [ ' add ' ]5 addAct ion . t i t l e6 u 'Add '

78 addAct ion . v a l u e9 u 'Add '

O action handler do AddForm realiza sequencia de acoes:

I chama o metodo create(data) passando os dados enviados noformulario

I chama o metodo add(object) com o resultado do create()

I redireciona para a URL retornada pelo metodo nextURL() sefoi finalizada a criacao do novo objeto

Page 15: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: form.AddForm.handleAdd

1 c l a s s AddForm(Form ) :2 ”””A f i e l d and button based add form . ”””3 zope . i n t e r f a c e . implements ( i n t e r f a c e s . IAddForm )4 i gno r eCon t e x t = True5 i gno r eReadon l y = True6 f i n i s h e dAdd = Fa l se78 @button . buttonAndHandler ( ( 'Add ' ) , name= ' add ' )9 def handleAdd ( s e l f , a c t i o n ) :

10 data , e r r o r s = s e l f . e x t r a c tDa ta ( )11 i f e r r o r s :12 s e l f . s t a t u s = s e l f . f o rmEr ro r sMessage13 re tu rn14 ob j = s e l f . createAndAdd ( data )15 i f ob j i s not None :16 # mark on l y as f i n i s h e d i f we17 # get the new ob j e c t18 s e l f . f i n i s h e dAdd = True

Page 16: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: form.AddForm.createAndAdd

1 c l a s s AddForm(Form ) :2 ”””A f i e l d and button based add form . ”””3 zope . i n t e r f a c e . implements ( i n t e r f a c e s . IAddForm )4 i gno r eCon t e x t = True5 i gno r eReadon l y = True6 f i n i s h e dAdd = Fa l se78 ## cut ##9

10 def createAndAdd ( s e l f , data ) :11 ob j = s e l f . c r e a t e ( data )12 even t = l i f e c y c l e e v e n t . Ob j ec tCrea tedEvent ( ob j )13 zope . even t . n o t i f y ( even t )14 s e l f . add ( ob j )15 re tu rn ob j

Page 17: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: renderizacao do formulario PersonAddForm

1 >>> p r i n t addForm ( ) # update ( ) e r e nd e r ( )2 <form a c t i o n=” . ”>3 <d i v c l a s s=”row”>4 < l a b e l f o r=”form−widgets−i d ”>ID</ l a b e l>5 < i n pu t type=” t e x t ” i d=”form−widgets−i d ”6 name=” form . w idge t s . i d ”7 c l a s s=” tex t−widget r e q u i r e d t e x t l i n e − f i e l d ”8 v a l u e=”” />9 </ d i v>

10 . . .11 <d i v c l a s s=” a c t i o n ”>12 < i n pu t type=” submit ”13 i d=”form−buttons−add”14 name=” form . bu t ton s . add”15 c l a s s=” submit−widget16 button− f i e l d ” v a l u e=”Add” />17 </ d i v>18 </ form>

Page 18: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: form.EditForm

1 c l a s s EditForm (Form ) :2 ”””A s imp l e e d i t form with an app l y button . ”””3 zope . i n t e r f a c e . implements ( i n t e r f a c e s . IEd i tForm )45 succe s sMessage = ( 'Data s u c c e s s f u l l y updated . ' )6 noChangesMessage = ( 'No changes were a p p l i e d . ' )78 @button . buttonAndHandler ( ( ' Apply ' ) , name= ' app l y ' )9 def handleApply ( s e l f , a c t i o n ) :

10 data , e r r o r s = s e l f . e x t r a c tDa ta ( )11 i f e r r o r s :12 s e l f . s t a t u s = s e l f . f o rmEr ro r sMessage13 re tu rn14 changes = s e l f . app lyChanges ( data )15 i f changes :16 s e l f . s t a t u s = s e l f . succe s sMessage17 e l s e :18 s e l f . s t a t u s = s e l f . noChangesMessage

Page 19: Formulários para Plone: um passeio pelo framework z3c.form

Exemplo: form.EditForm

1 c l a s s EditForm (Form ) :2 . .3 def applyChanges ( s e l f , data ) :4 con t en t = s e l f . ge tContent ( )5 changes = app lyChanges ( s e l f , content , data ) #**

6 # `` changes `` i s a d i c t i o n a r y ;7 # i f empty , t h e r e were no changes8 i f changes :9 # Cons t ru c t change−d e s c r i p t i o n s

10 # f o r the ob j e c t−mod i f i e d even t11 d e s c r i p t i o n s = [ ]12 f o r i n t e r f a c e , names i n changes . i t ems ( ) :13 d e s c r i p t i o n s . append (14 l i f e c y c l e e v e n t . A t t r i b u t e s ( i n t e r f a c e ,15 *names ) )16 # Send out a d e t a i l e d ob j e c t−mod i f i e d even t17 even t . n o t i f y (18 l i f e c y c l e e v e n t . Ob j e c tMod i f i edEven t (19 content ,20 * d e s c r i p t i o n s ) )21 re tu rn changes

Page 20: Formulários para Plone: um passeio pelo framework z3c.form

z3c.form e a integracao com Ploe:plone.app.z3cform

Para usar o template do pacote plone.app.z3c.form, e necessarioregistrar um novo skin Layer. No profile do seu produto, ao incluirplone.app.z3c.form como dependencia, ele automaticamenteinstala esse novo Layer e dessa forma teremos a validacao in-line eoutras melhorias no template padrao:Arquivo: meuproduto/profiles/default/metadata.xml

1 <metadata>2 <v e r s i o n>1</ v e r s i o n>3 <dependencies>4 <dependency>5 p r o f i l e −p lone . app . z3cform : d e f a u l t6 </dependency>7 </dependencies>8 </metadata>

Page 21: Formulários para Plone: um passeio pelo framework z3c.form

1 from p lone . z3cform . l a y o u t import wrap form2 from z3c . form import form , f i e l d34 c l a s s ApybMemberDisplayForm ( form . Form ) :5 mode = ' d i s p l a y '

6 f i e l d s = f i e l d . F i e l d s ( IApybMember ) . s e l e c t ( ' f u l l n ame ' ,7 ' o r g a n i z a t i o n ' , ' ema i l ' , ' c i t y ' , ' u f ' , ' t ype ' ,8 ' c ommun i t y r e l a t i o n ' )9 f i e l d s [ ' t ype ' ] . w i dge tFac to r y = r a d i o . Rad ioF i e l dWidge t

10 l a b e l = (u ' P e r f i l do Membro ' )11 d e s c r i p t i o n = (u ' ' ' Segue aba i xo os d e t a l h e s12 do p e r f i l do membro : ' ' ' )13 ...1415 MemberDisplayFormView = wrap form ( ApybMemberDisplayForm )

Page 22: Formulários para Plone: um passeio pelo framework z3c.form

1 from p lone . z3cform . l a y o u t import wrap form2 from z3c . form import form , f i e l d34 c l a s s ApybMemberDisplayForm ( form . Form ) :5 . .6 def getContent ( s e l f ) :7 s e s s i o n = Se s s i o n ( )8 ema i l = s e l f . r e q u e s t . ge t ( ' ema i l ' , None)9 query s e s s i o n . query ( model . ApybMember )

10 member = query . f i l t e r b y ( ema i l=ema i l )11 i f not member :12 s t a t u s = IS ta tu sMes sage ( s e l f . r e q u e s t )13 message = ”Cadas t ro de membro nao encont rado ”14 s t a t u s . addStatusMessage ( message , type= ' i n f o ' )15 u r l = s e l f . c on t e x t . a b s o l u t e u r l ( )16 re tu rn s e l f . r e q u e s t . r e s pon s e . r e d i r e c t ( u r l )17 e l s e :18 re tu rn member . one ( )1920 MemberDisplayFormView = wrap form ( ApybMemberDisplayForm )

Page 23: Formulários para Plone: um passeio pelo framework z3c.form

z3c.form: alterando o template de renderizacao doformulario

1 # Do not mix w i th :2 # Product s . F i v e . b rowse r V iewPageTemplateF i l e3 from zope . app . page temp la te import ViewPageTemplateFile\4 as Zope3PageTemplateF i l e56 c l a s MyForm( form . AddForm ) :7 ”””MyForm Example ”””8 temp la t e = Zope3PageTemplateF i l e ( ”my−t emp la t e . pt ” )

Page 24: Formulários para Plone: um passeio pelo framework z3c.form

z3c.form: alterando o template de renderizacao doformulario

1 # Do not mix w i th :2 # Product s . F i v e . b rowse r V iewPageTemplateF i l e3 from zope . app . page temp la te import ViewPageTemplateFile\4 as Zope3PageTemplateF i l e56 c l a s MyForm( form . AddForm ) :7 ”””MyForm Example ”””8 temp la t e = Zope3PageTemplateF i l e ( ”my−t emp la t e . pt ” )

Page 25: Formulários para Plone: um passeio pelo framework z3c.form

Perguntas?

Contato: Ruda Porto Filgueiras

I [email protected]

I @rudaporto

I github.com/rudaporto