[rql rewrite] backout 7177:f2a976cf7dac : since EXISTS is the variable scope, we want to insert snippets here anyway (other solution would be to NOT insert snippets at all in such case). Closes #1625464
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr## This file is part of CubicWeb.## CubicWeb is free software: you can redistribute it and/or modify it under the# terms of the GNU Lesser General Public License as published by the Free# Software Foundation, either version 2.1 of the License, or (at your option)# any later version.## CubicWeb is distributed in the hope that it will be useful, but WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more# details.## You should have received a copy of the GNU Lesser General Public License along# with CubicWeb. If not, see <http://www.gnu.org/licenses/>."""The default primary view"""__docformat__="restructuredtext en"_=unicodefromwarningsimportwarnfromlogilab.common.deprecationimportdeprecatedfromlogilab.mtconverterimportxml_escapefromcubicwebimportUnauthorized,NoSelectableObjectfromcubicweb.utilsimportsupport_argsfromcubicweb.selectorsimportmatch_kwargs,match_contextfromcubicweb.viewimportEntityViewfromcubicweb.schemaimportMETA_RTYPES,VIRTUAL_RTYPES,display_namefromcubicweb.webimportuicfg,componentclassPrimaryView(EntityView):"""the full view of an non final entity"""__regid__='primary'title=_('primary')show_attr_label=Trueshow_rel_label=Trueskip_none=Truersection=uicfg.primaryview_sectiondisplay_ctrl=uicfg.primaryview_display_ctrlmain_related_section=Truedefhtml_headers(self):"""return a list of html headers (eg something to be inserted between <head> and </head> of the returned page by default primary views are indexed """return[]defentity_call(self,entity):entity.complete()self.render_entity(entity)defrender_entity(self,entity):self.render_entity_toolbox(entity)self.render_entity_title(entity)# entity's attributes and relations, excluding meta data# if the entity isn't meta itselfifself.is_primary():boxes=self._prepare_side_boxes(entity)else:boxes=Noneifboxesorhasattr(self,'render_side_related'):self.w(u'<table width="100%"><tr><td style="width: 75%">')ifhasattr(self,'render_entity_summary'):warn('[3.10] render_entity_summary method is deprecated (%s)'%self,DeprecationWarning)self.render_entity_summary(entity)summary=self.summary(entity)ifsummary:warn('[3.10] summary method is deprecated (%s)'%self,DeprecationWarning)self.w(u'<div class="summary">%s</div>'%summary)self.w(u'<div class="mainInfo">')self.content_navigation_components('navcontenttop')self.render_entity_attributes(entity)ifself.main_related_section:self.render_entity_relations(entity)self.content_navigation_components('navcontentbottom')self.w(u'</div>')# side boxesifboxesorhasattr(self,'render_side_related'):self.w(u'</td><td>')self.w(u'<div class="primaryRight">')ifhasattr(self,'render_side_related'):warn('[3.2] render_side_related is deprecated')self.render_side_related(entity,[])self.render_side_boxes(boxes)self.w(u'</div>')self.w(u'</td></tr></table>')defcontent_navigation_components(self,context):self.w(u'<div class="%s">'%context)forcompinself._cw.vreg['ctxcomponents'].poss_visible_objects(self._cw,rset=self.cw_rset,view=self,context=context):# XXX bw compat codetry:comp.render(w=self.w,row=self.cw_row,view=self)exceptTypeError:comp.render(w=self.w)self.w(u'</div>')defrender_entity_title(self,entity):"""default implementation return dc_title"""title=xml_escape(entity.dc_title())iftitle:ifself.is_primary():self.w(u'<h1>%s</h1>'%title)else:atitle=self._cw._('follow this link for more information on this %s')%entity.dc_type()self.w(u'<h4><a href="%s" title="%s">%s</a></h4>'%(entity.absolute_url(),atitle,title))defrender_entity_toolbox(self,entity):self.content_navigation_components('ctxtoolbar')@deprecated('[3.8] render_entity_metadata method is deprecated')defrender_entity_metadata(self,entity):entity.view('metadata',w=self.w)defsummary(self,entity):"""default implementation return an empty string"""returnu''defrender_entity_attributes(self,entity):display_attributes=[]forrschema,_,role,dispctrlinself._section_def(entity,'attributes'):vid=dispctrl.get('vid','reledit')ifrschema.finalorvid=='reledit'ordispctrl.get('rtypevid'):value=entity.view(vid,rtype=rschema.type,role=role,initargs={'dispctrl':dispctrl})else:rset=self._relation_rset(entity,rschema,role,dispctrl)ifrset:value=self._cw.view(vid,rset)else:value=Noneifnotself.skip_noneor(valueisnotNoneandvalue!=''):display_attributes.append((rschema,role,dispctrl,value))ifdisplay_attributes:self.w(u'<table>')forrschema,role,dispctrl,valueindisplay_attributes:ifnothasattr(self,'_render_attribute'):label=self._rel_label(entity,rschema,role,dispctrl)self.render_attribute(label,value,table=True)elifsupport_args(self._render_attribute,'dispctrl'):warn('[3.9] _render_attribute prototype has changed and ''renamed to render_attribute, please update %s'%self.__class___,DeprecationWarning)self._render_attribute(dispctrl,rschema,value,role=role,table=True)else:self._render_attribute(rschema,value,role=role,table=True)warn('[3.6] _render_attribute prototype has changed and ''renamed to render_attribute, please update %s'%self.__class___,DeprecationWarning)self.w(u'</table>')defrender_attribute(self,label,value,table=False):self.field(label,value,tr=False,table=table)defrender_entity_relations(self,entity):forrschema,tschemas,role,dispctrlinself._section_def(entity,'relations'):ifrschema.finalordispctrl.get('rtypevid'):vid=dispctrl.get('vid','reledit')try:rview=self._cw.vreg['views'].select(vid,self._cw,rset=entity.cw_rset,row=entity.cw_row,col=entity.cw_col,dispctrl=dispctrl,rtype=rschema,role=role)exceptNoSelectableObject:continuevalue=rview.render(row=entity.cw_row,col=entity.cw_col,rtype=rschema.type,role=role)else:rset=self._relation_rset(entity,rschema,role,dispctrl)ifnotrset:continueifhasattr(self,'_render_relation'):ifnotsupport_args(self._render_relation,'showlabel'):self._render_relation(dispctrl,rset,'autolimited')warn('[3.9] _render_relation prototype has changed and has ''been renamed to render_relation, please update %s'%self.__class__,DeprecationWarning)else:self._render_relation(rset,dispctrl,'autolimited',self.show_rel_label)warn('[3.6] _render_relation prototype has changed and has ''been renamed to render_relation, please update %s'%self.__class__,DeprecationWarning)continuevid=dispctrl.get('vid','autolimited')try:rview=self._cw.vreg['views'].select(vid,self._cw,rset=rset,dispctrl=dispctrl)exceptNoSelectableObject:continuevalue=rview.render()label=self._rel_label(entity,rschema,role,dispctrl)self.render_relation(label,value)defrender_relation(self,label,value):self.w(u'<div class="section">')iflabel:self.w(u'<h4>%s</h4>'%label)self.w(value)self.w(u'</div>')defrender_side_boxes(self,boxes):"""display side related relations: non-meta in a first step, meta in a second step """forboxinboxes:ifisinstance(box,tuple):try:label,rset,vid,dispctrl=boxexceptValueError:label,rset,vid=boxdispctrl={}warn('[3.10] box views should now be a RsetBox instance, ''please update %s'%self.__class__.__name__,DeprecationWarning)self.w(u'<div class="sideBox">')self.wview(vid,rset,title=label,initargs={'dispctrl':dispctrl})self.w(u'</div>')else:try:box.render(w=self.w,row=self.cw_row)exceptTypeError:box.render(w=self.w)def_prepare_side_boxes(self,entity):sideboxes=[]boxesreg=self._cw.vreg['ctxcomponents']forrschema,tschemas,role,dispctrlinself._section_def(entity,'sideboxes'):rset=self._relation_rset(entity,rschema,role,dispctrl)ifnotrset:continuelabel=self._rel_label(entity,rschema,role,dispctrl)vid=dispctrl.get('vid','autolimited')box=boxesreg.select('rsetbox',self._cw,rset=rset,vid=vid,title=label,dispctrl=dispctrl,context='incontext')sideboxes.append(box)sideboxes+=boxesreg.poss_visible_objects(self._cw,rset=self.cw_rset,view=self,context='incontext')# XXX since we've two sorted list, it may be worth using bisectdefget_order(x):if'order'inx.cw_property_defs:returnx.cw_propval('order')# default to 9999 so view boxes occurs after component boxesreturnx.cw_extra_kwargs.get('dispctrl',{}).get('order',9999)returnsorted(sideboxes,key=get_order)def_section_def(self,entity,where):rdefs=[]eschema=entity.e_schemaforrschema,tschemas,roleineschema.relation_definitions(True):ifrschemainVIRTUAL_RTYPES:continuematchtschemas=[]fortschemaintschemas:section=self.rsection.etype_get(eschema,rschema,role,tschema)ifsection==where:matchtschemas.append(tschema)ifmatchtschemas:dispctrl=self.display_ctrl.etype_get(eschema,rschema,role,'*')rdefs.append((rschema,matchtschemas,role,dispctrl))returnsorted(rdefs,key=lambdax:x[-1]['order'])def_relation_rset(self,entity,rschema,role,dispctrl):try:rset=entity.related(rschema.type,role)exceptUnauthorized:returnif'filter'indispctrl:rset=dispctrl['filter'](rset)returnrsetdef_rel_label(self,entity,rschema,role,dispctrl):ifrschema.final:showlabel=dispctrl.get('showlabel',self.show_attr_label)else:showlabel=dispctrl.get('showlabel',self.show_rel_label)ifshowlabel:ifdispctrl.get('label'):label=self._cw._(dispctrl['label'])else:label=display_name(self._cw,rschema.type,role,context=entity.__regid__)returnlabelreturnu''classRelatedView(EntityView):"""Display a rset, usually containing entities linked to another entity being displayed. It will try to display nicely according to the number of items in the result set. """__regid__='autolimited'defcall(self,**kwargs):if'dispctrl'inself.cw_extra_kwargs:if'limit'inself.cw_extra_kwargs['dispctrl']:limit=self.cw_extra_kwargs['dispctrl']['limit']else:limit=self._cw.property_value('navigation.related-limit')list_limit=self.cw_extra_kwargs['dispctrl'].get('use_list_limit',5)subvid=self.cw_extra_kwargs['dispctrl'].get('subvid','incontext')else:limit=list_limit=Nonesubvid='incontext'iflimitisNoneorself.cw_rset.rowcount<=limit:ifself.cw_rset.rowcount==1:self.wview(subvid,self.cw_rset,row=0)eliflist_limitisNoneor1<self.cw_rset.rowcount<=list_limit:self.wview('csv',self.cw_rset,subvid=subvid)else:self.w(u'<div>')self.wview('simplelist',self.cw_rset,subvid=subvid)self.w(u'</div>')# else show links to display related entitieselse:rql=self.cw_rset.printable_rql()rset=self.cw_rset.limit(limit)# remove extra entityiflist_limitisNone:self.wview('csv',rset,subvid=subvid)self.w(u'[<a href="%s">%s</a>]'%(xml_escape(self._cw.build_url(rql=rql,vid=subvid)),self._cw._('see them all')))else:self.w(u'<div>')self.wview('simplelist',rset,subvid=subvid)self.w(u'[<a href="%s">%s</a>]'%(xml_escape(self._cw.build_url(rql=rql,vid=subvid)),self._cw._('see them all')))self.w(u'</div>')classURLAttributeView(EntityView):"""use this view for attributes whose value is an url and that you want to display as clickable link """__regid__='urlattr'__select__=EntityView.__select__&match_kwargs('rtype')defcell_call(self,row,col,rtype,**kwargs):entity=self.cw_rset.get_entity(row,col)url=entity.printable_value(rtype)ifurl:self.w(u'<a href="%s">%s</a>'%(url,url))classAttributeView(EntityView):"""use this view on an entity as an alternative to more sophisticated views such as reledit. Ex. usage: uicfg.primaryview_display_ctrl.tag_attribute(('Foo', 'bar'), {'vid': 'attribute'}) """__regid__='attribute'__select__=EntityView.__select__&match_kwargs('rtype')defcell_call(self,row,col,rtype,role,**kwargs):entity=self.cw_rset.get_entity(row,col)ifself._cw.vreg.schema.rschema(rtype).final:self.w(entity.printable_value(rtype))else:dispctrl=uicfg.primaryview_display_ctrl.etype_get(entity.e_schema,rtype,role,'*')rset=entity.related(rtype,role)ifrset:self.wview('autolimited',rset,initargs={'dispctrl':dispctrl})classToolbarLayout(component.Layout):__select__=match_context('ctxtoolbar')defrender(self,w):ifself.init_rendering():self.cw_extra_kwargs['view'].render_body(w)## default primary ui configuration ###########################################_pvs=uicfg.primaryview_sectionforrtypeinMETA_RTYPES:_pvs.tag_subject_of(('*',rtype,'*'),'hidden')_pvs.tag_object_of(('*',rtype,'*'),'hidden')_pvs.tag_subject_of(('*','require_permission','*'),'hidden')_pvs.tag_object_of(('*','require_permission','*'),'hidden')