"""abstract form classes for CubicWeb web client:organization: Logilab:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses"""__docformat__="restructuredtext en"fromcubicweb.appobjectimportAppObjectfromcubicweb.viewimportNOINDEX,NOFOLLOWfromcubicweb.commonimporttagsfromcubicweb.webimportstdmsgs,httpcache,formfieldsclassFormViewMixIn(object):"""abstract form view mix-in"""category='form'http_cache_manager=httpcache.NoHTTPCacheManageradd_to_breadcrumbs=Falsedefhtml_headers(self):"""return a list of html headers (eg something to be inserted between <head> and </head> of the returned page by default forms are neither indexed nor followed """return[NOINDEX,NOFOLLOW]deflinkable(self):"""override since forms are usually linked by an action, so we don't want them to be listed by appli.possible_views """returnFalseclassmetafieldsform(type):"""metaclass for FieldsForm to retrieve fields defined as class attributes and put them into a single ordered list: '_fields_'. """def__new__(mcs,name,bases,classdict):allfields=[]forbaseinbases:ifhasattr(base,'_fields_'):allfields+=base._fields_clsfields=(itemforiteminclassdict.items()ifisinstance(item[1],formfields.Field))forfieldname,fieldinsorted(clsfields,key=lambdax:x[1].creation_rank):ifnotfield.name:field.set_name(fieldname)allfields.append(field)classdict['_fields_']=allfieldsreturnsuper(metafieldsform,mcs).__new__(mcs,name,bases,classdict)classFieldNotFound(Exception):"""raised by field_by_name when a field with the given name has not been found """classForm(AppObject):__metaclass__=metafieldsform__registry__='forms'def__init__(self,req,rset,**kwargs):super(Form,self).__init__(req,rset=rset,**kwargs)self.restore_previous_post(self.session_key())defsession_key(self):"""return the key that may be used to store / retreive data about a previous post which failed because of a validation error """return'%s#%s'%(self._cw.url(),self.domid)defrestore_previous_post(self,sessionkey):# get validation session data which may have been previously set.# deleting validation errors here breaks form reloading (errors are# no more available), they have to be deleted by application's publish# method on successful commitforminfo=self._cw.get_session_data(sessionkey,pop=True)ifforminfo:# XXX remove req.data assigment once cw.web.widget is killedself._cw.data['formvalues']=self.form_previous_values=forminfo['values']self._cw.data['formerrors']=self.form_valerror=forminfo['errors']self._cw.data['displayederrors']=self.form_displayed_errors=set()# if some validation error occured on entity creation, we have to# get the original variable name from its attributed eidforeid=self.form_valerror.entityforvar,eidinforminfo['eidmap'].items():ifforeid==eid:self.form_valerror.eid=varbreakelse:self.form_valerror.eid=foreidelse:self.form_previous_values={}self.form_valerror=None