merge tls-sprint
authorGraziella Toutoungis <graziella.toutoungis@logilab.fr>
Mon, 11 May 2009 12:03:52 +0200
branchtls-sprint
changeset 1725 d15406d17803
parent 1724 8a3c3ae8c809 (current diff)
parent 1723 30c3a713ab61 (diff)
child 1726 08918409815e
child 1728 296f0eda7f67
merge
web/views/schema.py
--- a/appobject.py	Mon May 11 11:59:56 2009 +0200
+++ b/appobject.py	Mon May 11 12:03:52 2009 +0200
@@ -194,7 +194,7 @@
             if __fallback_vid is None:
                 raise
             view = self.vreg.select_view(__fallback_vid, self.req, rset, **kwargs)
-        return view.dispatch(**kwargs)
+        return view.render(**kwargs)
 
     # url generation methods ##################################################
 
--- a/cwvreg.py	Mon May 11 11:59:56 2009 +0200
+++ b/cwvreg.py	Mon May 11 12:03:52 2009 +0200
@@ -189,7 +189,7 @@
         except KeyError:
             rset = None
         selected = self.select(objclss, req, rset, **context)
-        return selected.dispatch(**context)
+        return selected.render(**context)
 
     def main_template(self, req, oid='main-template', **context):
         """display query by calling the given template (default to main),
--- a/entity.py	Mon May 11 11:59:56 2009 +0200
+++ b/entity.py	Mon May 11 12:03:52 2009 +0200
@@ -51,11 +51,11 @@
     def _dispatch_rtags(tags, rtype, role, stype, otype):
         for tag in tags:
             if tag in _MODE_TAGS:
-                uicfg.rmode.tag_relation(tag, (stype, rtype, otype), role)
+                uicfg.rmode.tag_relation(stype, rtype, otype, tag, role)
             elif tag in _CATEGORY_TAGS:
-                uicfg.rcategories.tag_relation(tag, (stype, rtype, otype), role)
+                uicfg.rcategories.tag_relation(stype, rtype, otype, tag, role)
             elif tag == 'inlineview':
-                uicfg.rinlined.tag_relation(True, (stype, rtype, otype), role)
+                uicfg.rinlined.tag_relation(stype, rtype, otype, True, role)
             else:
                 raise ValueError(tag)
 
@@ -129,7 +129,7 @@
                     widget = getattr(formwidgets, wdgname)
                     assert hasattr(widget, 'render')
                     AutomaticEntityForm.rwidgets.tag_relation(
-                        widget, (etype, rtype, '*'), 'subject')
+                        etype, rtype, '*', widget, tagged='subject')
         return super(_metaentity, mcs).__new__(mcs, name, bases, classdict)
 
 
--- a/rtags.py	Mon May 11 11:59:56 2009 +0200
+++ b/rtags.py	Mon May 11 12:03:52 2009 +0200
@@ -28,8 +28,24 @@
         return self.get(*key)
     __contains__ = __getitem__
 
-    def _get_keys(self, rtype, tagged, stype, otype):
-        assert tagged in ('subject', 'object'), tagged
+    def _get_tagged(self, stype, otype, tagged=None):
+        stype, otype = str(stype), str(otype)
+        if tagged is None:
+            if stype[0] == '!':
+                tagged = 'subject'
+                stype = stype[1:]
+            elif otype[0] == '!':
+                tagged = 'object'
+                otype = otype[1:]
+            else:
+                raise AssertionError('either stype or rtype should have the '
+                                     'role mark ("!")')
+        else:
+            assert tagged in ('subject', 'object'), tagged
+        return stype, otype, tagged
+
+    def _get_keys(self, stype, rtype, otype, tagged=None):
+        stype, otype, tagged = self._get_tagged(stype, otype, tagged)
         keys = [(rtype, tagged, '*', '*'),
                 (rtype, tagged, '*', otype),
                 (rtype, tagged, stype, '*'),
@@ -42,46 +58,43 @@
                 keys.remove((rtype, tagged, stype, '*'))
         return keys
 
-    def tag_attribute(self, tag, stype, attr):
-        self._tagdefs[(str(attr), 'subject', str(stype), '*')] = tag
+    def tag_relation(self, stype, rtype, otype, tag, tagged=None):
+        stype, otype, tagged = self._get_tagged(stype, otype, tagged)
+        self._tagdefs[(str(rtype), tagged, stype, otype)] = tag
 
-    def tag_relation(self, tag, relation, tagged):
-        assert tagged in ('subject', 'object'), tagged
-        stype, rtype, otype = relation
-        self._tagdefs[(str(rtype), tagged, str(stype), str(otype))] = tag
+    def tag_attribute(self, stype, attr, tag):
+        self.tag_relation(stype, attr, '*', tag, 'subject')
 
-    def del_rtag(self, relation, tagged):
-        assert tagged in ('subject', 'object'), tagged
-        stype, rtype, otype = relation
-        del self._tagdefs[(str(rtype), tagged, str(stype), str(otype))]
+    def del_rtag(self, stype, rtype, otype):
+        stype, otype, tagged = self._get_tagged(stype, otype)
+        del self._tagdefs[(str(rtype), tagged, stype, otype)]
 
-    def get(self, rtype, tagged, stype='*', otype='*'):
-        for key in reversed(self._get_keys(rtype, tagged, stype, otype)):
+    def get(self, stype, rtype, otype, tagged=None):
+        for key in reversed(self._get_keys(stype, rtype, otype, tagged)):
             try:
                 return self._tagdefs[key]
             except KeyError:
                 continue
         return None
 
-    def etype_get(self, etype, rtype, tagged, ttype='*'):
-        if tagged == 'subject':
-            return self.get(rtype, tagged, etype, ttype)
-        return self.get(rtype, tagged, ttype, etype)
+    def etype_get(self, etype, rtype, role, ttype='*'):
+        if role == 'subject':
+            return self.get(etype, rtype, ttype, role)
+        return self.get(ttype, rtype, etype, role)
 
 
 
 class RelationTagsSet(RelationTags):
     """This class associates a set of tags to each key."""
 
-    def tag_relation(self, tag, relation, tagged):
-        assert tagged in ('subject', 'object'), tagged
-        stype, rtype, otype = relation
+    def tag_relation(self, stype, rtype, otype, tag, tagged=None):
+        stype, otype, tagged = self._get_tagged(stype, otype, tagged)
         rtags = self._tagdefs.setdefault((rtype, tagged, stype, otype), set())
         rtags.add(tag)
 
-    def get(self, rtype, tagged, stype='*', otype='*'):
+    def get(self, stype, rtype, otype, tagged=None):
         rtags = set()
-        for key in self._get_keys(rtype, tagged, stype, otype):
+        for key in self._get_keys(stype, rtype, otype, tagged):
             try:
                 rtags.update(self._tagdefs[key])
             except KeyError:
--- a/sobjects/notification.py	Mon May 11 11:59:56 2009 +0200
+++ b/sobjects/notification.py	Mon May 11 12:03:52 2009 +0200
@@ -198,8 +198,9 @@
             # since the same view (eg self) may be called multiple time and we
             # need a fresh stream at each iteration, reset it explicitly
             self.w = None
-            # call dispatch before subject to set .row/.col attributes on the view :/
-            content = self.dispatch(row=0, col=0, **kwargs)
+            # XXX call render before subject to set .row/.col attributes on the
+            #     view
+            content = self.render(row=0, col=0, **kwargs)
             subject = self.subject()
             msg = format_mail(userdata, [emailaddr], content, subject,
                               config=self.config, msgid=msgid, references=refs)
--- a/sobjects/supervising.py	Mon May 11 11:59:56 2009 +0200
+++ b/sobjects/supervising.py	Mon May 11 12:03:52 2009 +0200
@@ -19,7 +19,7 @@
     events = ('before_add_relation', 'before_delete_relation',
               'after_add_entity', 'before_update_entity')
     accepts = ('Any',)
-    
+
     def call(self, session, *args):
         dest = self.config['supervising-addrs']
         if not dest: # no supervisors, don't do this for nothing...
@@ -27,24 +27,24 @@
         self.session = session
         if self._call(*args):
             SupervisionMailOp(session)
-        
+
     def _call(self, *args):
         if self._event() == 'update_entity' and args[0].e_schema == 'CWUser':
             updated = set(args[0].iterkeys())
             if not (updated - frozenset(('eid', 'modification_date', 'last_login_time'))):
-                # don't record last_login_time update which are done 
+                # don't record last_login_time update which are done
                 # automatically at login time
                 return False
         self.session.add_query_data('pendingchanges', (self._event(), args))
         return True
-        
+
     def _event(self):
         return self.event.split('_', 1)[1]
 
 
 class EntityDeleteHook(SomethingChangedHook):
     events = ('before_delete_entity',)
-    
+
     def _call(self, eid):
         entity = self.session.entity(eid)
         try:
@@ -80,19 +80,19 @@
                 changes.remove(change)
                 if entity.from_state:
                     try:
-                        changes.remove( ('delete_relation', 
-                                         (entity.wf_info_for[0].eid, 'in_state', 
+                        changes.remove( ('delete_relation',
+                                         (entity.wf_info_for[0].eid, 'in_state',
                                           entity.from_state[0].eid)) )
                     except ValueError:
                         pass
                     try:
-                        changes.remove( ('add_relation', 
-                                         (entity.wf_info_for[0].eid, 'in_state', 
+                        changes.remove( ('add_relation',
+                                         (entity.wf_info_for[0].eid, 'in_state',
                                           entity.to_state[0].eid)) )
                     except ValueError:
                         pass
                     event = 'change_state'
-                    change = (event, 
+                    change = (event,
                               (entity.wf_info_for[0],
                                entity.from_state[0], entity.to_state[0]))
                     changes.append(change)
@@ -115,7 +115,7 @@
                 #     at entity creation time
                 elif changedescr[1] == 'in_state' and changedescr[0] in added:
                     index['add_relation'].remove(change)
-                    
+
         except KeyError:
             break
     for eid in deleted:
@@ -146,10 +146,10 @@
 
     def recipients(self):
         return self.config['supervising-addrs']
-        
+
     def subject(self):
         return self.req._('[%s supervision] changes summary') % self.config.appid
-    
+
     def call(self, changes):
         user = self.req.actual_session().user
         self.w(self.req._('user %s has made the following change(s):\n\n')
@@ -163,30 +163,30 @@
         return {'eid': entity.eid,
                 'etype': entity.dc_type().lower(),
                 'title': entity.dc_title()}
-    
+
     def add_entity(self, entity):
         msg = self.req._('added %(etype)s #%(eid)s (%(title)s)')
         self.w(u'%s\n' % (msg % self._entity_context(entity)))
         self.w(u'  %s' % entity.absolute_url())
-            
+
     def update_entity(self, entity):
         msg = self.req._('updated %(etype)s #%(eid)s (%(title)s)')
         self.w(u'%s\n' % (msg % self._entity_context(entity)))
         # XXX print changes
         self.w(u'  %s' % entity.absolute_url())
-            
+
     def delete_entity(self, eid, etype, title):
         msg = self.req._('deleted %(etype)s #%(eid)s (%(title)s)')
         etype = display_name(self.req, etype).lower()
         self.w(msg % locals())
-        
+
     def change_state(self, entity, fromstate, tostate):
         msg = self.req._('changed state of %(etype)s #%(eid)s (%(title)s)')
         self.w(u'%s\n' % (msg % self._entity_context(entity)))
-        self.w(_('  from state %(fromstate)s to state %(tostate)s\n' % 
+        self.w(_('  from state %(fromstate)s to state %(tostate)s\n' %
                  {'fromstate': _(fromstate.name), 'tostate': _(tostate.name)}))
         self.w(u'  %s' % entity.absolute_url())
-        
+
     def _relation_context(self, fromeid, rtype, toeid):
         _ = self.req._
         session = self.req.actual_session()
@@ -202,7 +202,7 @@
                 'frometype': describe(fromeid),
                 'toeid': toeid,
                 'toetype': describe(toeid)}
-        
+
     def add_relation(self, fromeid, rtype, toeid):
         msg = self.req._('added relation %(rtype)s from %(frometype)s #%(fromeid)s to %(toetype)s #%(toeid)s')
         self.w(msg % self._relation_context(fromeid, rtype, toeid))
@@ -210,8 +210,8 @@
     def delete_relation(self, fromeid, rtype, toeid):
         msg = self.req._('deleted relation %(rtype)s from %(frometype)s #%(fromeid)s to %(toetype)s #%(toeid)s')
         self.w(msg % self._relation_context(fromeid, rtype, toeid))
-        
-                
+
+
 class SupervisionMailOp(SendMailOp):
     """special send email operation which should be done only once for a bunch
     of changes
@@ -219,14 +219,14 @@
     def _get_view(self):
         return self.session.vreg.select_component('supervision_notif',
                                                   self.session, None)
-        
+
     def _prepare_email(self):
         session = self.session
         config = session.vreg.config
         uinfo = {'email': config['sender-addr'],
                  'name': config['sender-name']}
         view = self._get_view()
-        content = view.dispatch(changes=session.query_data('pendingchanges'))
+        content = view.render(changes=session.query_data('pendingchanges'))
         recipients = view.recipients()
         msg = format_mail(uinfo, recipients, content, view.subject(), config=config)
         self.to_send = [(msg, recipients)]
--- a/sobjects/test/unittest_notification.py	Mon May 11 11:59:56 2009 +0200
+++ b/sobjects/test/unittest_notification.py	Mon May 11 12:03:52 2009 +0200
@@ -22,7 +22,7 @@
         self.failUnlessEqual(values['eid'], '21')
         self.failUnless('timestamp' in values)
         self.failUnlessEqual(parse_message_id(msgid1[1:-1], 'anotherapp'), None)
-        
+
     def test_notimestamp(self):
         msgid1 = construct_message_id('testapp', 21, False)
         msgid2 = construct_message_id('testapp', 21, False)
@@ -39,7 +39,7 @@
         for eid in (1, 12, 123, 1234):
             msgid1 = construct_message_id('testapp', eid, 12)
             self.assertNotEquals(msgid1, '<@testapp.%s>' % gethostname())
-        
+
 
 class RecipientsFinderTC(EnvBasedTC):
     def test(self):
@@ -57,19 +57,19 @@
         self.set_option('default-recipients-mode', 'default-dest-addrs')
         self.set_option('default-dest-addrs', 'abcd@logilab.fr, efgh@logilab.fr')
         self.assertEquals(finder.recipients(), [('abcd@logilab.fr', 'en'), ('efgh@logilab.fr', 'en')])
-        
+
 
 class StatusChangeViewsTC(EnvBasedTC):
-        
+
     def test_status_change_view(self):
         req = self.session()
         u = self.create_user('toto', req=req)
         assert u.req
         self.execute('SET X in_state S WHERE X eid %s, S name "deactivated"' % u.eid)
         v = self.vreg.select_view('notif_status_change', req, u.rset, row=0)
-        content = v.dispatch(row=0, comment='yeah',
-                             previous_state='activated',
-                             current_state='deactivated')
+        content = v.render(row=0, comment='yeah',
+                           previous_state='activated',
+                           current_state='deactivated')
         # remove date
         self.assertEquals(content,
                           '''
--- a/sobjects/test/unittest_supervising.py	Mon May 11 11:59:56 2009 +0200
+++ b/sobjects/test/unittest_supervising.py	Mon May 11 12:03:52 2009 +0200
@@ -17,12 +17,12 @@
         self.execute('SET C comments B WHERE B title "une autre news !", C content "Yo !"')
         self.vreg.config.global_set_option('supervising-addrs', 'test@logilab.fr')
 
-        
+
     def test_supervision(self):
         session = self.session()
         # do some modification
         ueid = self.execute('INSERT CWUser X: X login "toto", X upassword "sosafe", X in_group G, X in_state S '
-                            'WHERE G name "users", S name "activated"')[0][0]        
+                            'WHERE G name "users", S name "activated"')[0][0]
         self.execute('SET X last_login_time NOW WHERE X eid %(x)s', {'x': ueid}, 'x')
         self.execute('SET X in_state S WHERE X login "anon", S name "deactivated"')
         self.execute('DELETE Card B WHERE B title "une news !"')
@@ -38,7 +38,7 @@
         view = sentops[0]._get_view()
         self.assertEquals(view.recipients(), ['test@logilab.fr'])
         self.assertEquals(view.subject(), '[data supervision] changes summary')
-        data = view.dispatch(changes=session.query_data('pendingchanges')).strip()
+        data = view.render(changes=session.query_data('pendingchanges')).strip()
         data = re.sub('#\d+', '#EID', data)
         data = re.sub('/\d+', '/EID', data)
         self.assertTextEquals('''user admin has made the following change(s):
@@ -63,9 +63,9 @@
                               data)
         # check prepared email
         op._prepare_email()
-        self.assertEquals(len(op.to_send), 1) 
+        self.assertEquals(len(op.to_send), 1)
         self.assert_(op.to_send[0][0])
-        self.assertEquals(op.to_send[0][1], ['test@logilab.fr']) 
+        self.assertEquals(op.to_send[0][1], ['test@logilab.fr'])
 
     def test_nonregr1(self):
         session = self.session()
@@ -73,6 +73,6 @@
         self.execute('SET X last_login_time NOW WHERE X eid %(x)s', {'x': session.user.eid}, 'x')
         self.commit() # no crash
 
-        
+
 if __name__ == '__main__':
     unittest_main()
--- a/test/unittest_rtags.py	Mon May 11 11:59:56 2009 +0200
+++ b/test/unittest_rtags.py	Mon May 11 12:03:52 2009 +0200
@@ -5,14 +5,23 @@
 
     def test_rtags_expansion(self):
         rtags = RelationTags()
-        rtags.tag_relation('primary', ('Societe', 'travaille', '*'), 'subject', )
-        rtags.tag_relation('secondary', ('*', 'evaluee', '*'), 'subject')
-        rtags.tag_relation('generated', ('*', 'tags', '*'), 'object')        
-        self.assertEquals(rtags.get('evaluee', 'subject', 'Note'), 'secondary')
-        self.assertEquals(rtags.get('travaille', 'subject', 'Societe'), 'primary')
-        self.assertEquals(rtags.get('travaille', 'subject', 'Note'), None)
-        self.assertEquals(rtags.get('tags', 'subject', 'Note'), None)
-        self.assertEquals(rtags.get('tags', 'object', 'Note'), 'generated')
+        rtags.tag_relation('!Societe', 'travaille', '*', 'primary')
+        rtags.tag_relation('!*', 'evaluee', '*', 'secondary')
+        rtags.tag_relation('*', 'tags', '!*', 'generated')
+        self.assertEquals(rtags.get('!Note', 'evaluee', '*'),
+                          'secondary')
+        self.assertEquals(rtags.get('Note', 'evaluee', '*', 'subject'),
+                          'secondary')
+        self.assertEquals(rtags.get('!Societe', 'travaille', '*'),
+                          'primary')
+        self.assertEquals(rtags.get('!Note', 'travaille', '*'),
+                          None)
+        self.assertEquals(rtags.get('!Note', 'tags', '*'),
+                          None)
+        self.assertEquals(rtags.get('*', 'tags', '!Note'),
+                          'generated')
+        self.assertEquals(rtags.get('Tag', 'tags', '!*'),
+                          'generated')
 
 #         self.assertEquals(rtags.rtag('evaluee', 'Note', 'subject'), set(('secondary', 'link')))
 #         self.assertEquals(rtags.is_inlined('evaluee', 'Note', 'subject'), False)
@@ -35,11 +44,16 @@
 
     def test_rtagset_expansion(self):
         rtags = RelationTagsSet()
-        rtags.tag_relation('primary', ('Societe', 'travaille', '*'), 'subject', )
-        rtags.tag_relation('secondary', ('*', 'travaille', '*'), 'subject')
-        self.assertEquals(rtags.get('travaille', 'subject', 'Societe'), set(('primary', 'secondary')))
-        self.assertEquals(rtags.get('travaille', 'subject', 'Note'), set(('secondary',)))
-        self.assertEquals(rtags.get('tags', 'subject', 'Note'), set())
+        rtags.tag_relation('!Societe', 'travaille', '*', 'primary')
+        rtags.tag_relation('!*', 'travaille', '*', 'secondary')
+        self.assertEquals(rtags.get('!Societe', 'travaille', '*'),
+                          set(('primary', 'secondary')))
+        self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
+                          set(('primary', 'secondary')))
+        self.assertEquals(rtags.get('!Note', 'travaille', '*'),
+                          set(('secondary',)))
+        self.assertEquals(rtags.get('!Note', 'tags', "*"),
+                          set())
 
 if __name__ == '__main__':
     unittest_main()
--- a/view.py	Mon May 11 11:59:56 2009 +0200
+++ b/view.py	Mon May 11 12:03:52 2009 +0200
@@ -125,7 +125,7 @@
 
     # main view interface #####################################################
 
-    def dispatch(self, w=None, **context):
+    def render(self, w=None, **context):
         """called to render a view object for a result set.
 
         This method is a dispatched to an actual method selected
@@ -150,6 +150,8 @@
         if stream is not None:
             return self._stream.getvalue()
 
+    dispatch = obsolete('.dispatch is deprecated, use .render')(render)
+
     # should default .call() method add a <div classs="section"> around each
     # rset item
     add_div_section = True
--- a/web/test/unittest_views_editforms.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/test/unittest_views_editforms.py	Mon May 11 12:03:52 2009 +0200
@@ -9,13 +9,12 @@
 class AutomaticEntityFormTC(EnvBasedTC):
 
     def test_custom_widget(self):
-        AEF.rwidgets.tag_relation(AutoCompletionWidget,
-                                  ('CWUser', 'login', '*'), 'subject')
+        AEF.rwidgets.tag_relation('!CWUser', 'login', '*', AutoCompletionWidget)
         form = self.vreg.select_object('forms', 'edition', self.request(), None,
                                        entity=self.user())
         field = form.field_by_name('login')
         self.assertIsInstance(field.widget, AutoCompletionWidget)
-        AEF.rwidgets.del_rtag(('CWUser', 'login', '*'),'subject')
+        AEF.rwidgets.del_rtag('!CWUser', 'login', '*')
 
 
     def test_euser_relations_by_category(self):
--- a/web/test/unittest_views_navigation.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/test/unittest_views_navigation.py	Mon May 11 12:03:52 2009 +0200
@@ -9,7 +9,7 @@
 BreadCrumbEntityVComponent.visible = True
 
 class NavigationTC(EnvBasedTC):
-    
+
     def test_navigation_selection(self):
         rset = self.execute('Any X,N WHERE X name N')
         req = self.request()
@@ -39,29 +39,29 @@
         req.set_search_state('W:X:Y:Z')
         navcomp = self.vreg.select_component('navigation', req, rset)
         self.assertIsInstance(navcomp, SortedNavigation)
-        
-        
+
+
     def test_sorted_navigation(self):
         rset = self.execute('Any X,N ORDERBY N WHERE X name N')
         req = self.request()
         req.set_search_state('W:X:Y:Z')
         navcomp = self.vreg.select_component('navigation', rset.req, rset)
-        html = navcomp.dispatch()
+        html = navcomp.render()
         rset = self.execute('Any RDEF ORDERBY RT WHERE RDEF relation_type RT')
         navcomp = self.vreg.select_component('navigation', req, rset)
-        html = navcomp.dispatch()
+        html = navcomp.render()
         rset = self.execute('Any RDEF ORDERBY RDEF WHERE RDEF relation_type RT')
         navcomp = self.vreg.select_component('navigation', req, rset)
-        html = navcomp.dispatch()
+        html = navcomp.render()
         rset = self.execute('CWAttribute RDEF ORDERBY RDEF')
         navcomp = self.vreg.select_component('navigation', req, rset)
-        html = navcomp.dispatch()
+        html = navcomp.render()
         rset = self.execute('Any RDEF ORDERBY N WHERE RDEF relation_type RT, RT name N')
         navcomp = self.vreg.select_component('navigation', req, rset)
-        html = navcomp.dispatch()
+        html = navcomp.render()
         rset = self.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N WHERE RDEF relation_type RT, RT name N')
         navcomp = self.vreg.select_component('navigation', rset.req, rset)
-        html = navcomp.dispatch()
+        html = navcomp.render()
 
 
 
@@ -87,15 +87,15 @@
         req.cnx.commit()
         objs = self.vreg.possible_vobjects('contentnavigation', req, rset,
                                           view=view, context='navbottom')
-        
+
         clsids = [obj.id for obj in objs]
         self.failUnless('breadcrumbs' in clsids)
         objs = self.vreg.possible_vobjects('contentnavigation', req, rset,
                                           view=view, context='navtop')
-        
+
         clsids = [obj.id for obj in objs]
         self.failIf('breadcrumbs' in clsids)
-        
+
 
 if __name__ == '__main__':
     unittest_main()
--- a/web/uicfg.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/uicfg.py	Mon May 11 12:03:52 2009 +0200
@@ -34,10 +34,11 @@
         super(RDisplayRelationTags, self).__init__()
         self._counter = 0
 
-    def tag_relation(self, values, *args, **kwargs):
-        super(RDisplayRelationTags, self).tag_relation(values, *args, **kwargs)
-        if values:
-            values['order'] = self.get_timestamp()
+    def tag_relation(self, stype, rtype, otype, tag, tagged=None):
+        super(RDisplayRelationTags, self).tag_relation(stype, rtype, otype, tag,
+                                                       tagged)
+        if tag:
+            tag['order'] = self.get_timestamp()
 
     def get_timestamp(self):
         self._counter += 1
@@ -50,8 +51,8 @@
               'in_state', 'wf_info_for', 'require_permission',
               'from_entity', 'to_entity',
               'see_also'):
-    rdisplay.tag_relation({}, ('*', rtype, '*'), 'subject')
-    rdisplay.tag_relation({}, ('*', rtype, '*'), 'object')
+    rdisplay.tag_relation('!*', rtype, '*', {})
+    rdisplay.tag_relation('*', rtype, '!*', {})
 
 
 # index view configuration ####################################################
@@ -69,25 +70,26 @@
 # relations'category (eg primary/secondary/generic/metadata/generated)
 rcategories = RelationTags()
 # use primary and not generated for eid since it has to be an hidden
-rcategories.tag_relation('primary', ('*', 'eid', '*'), 'subject')
-rcategories.tag_relation('primary', ('*', 'in_state', '*'), 'subject')
-rcategories.tag_relation('secondary', ('*', 'description', '*'), 'subject')
-rcategories.tag_relation('metadata', ('*', 'creation_date', '*'), 'subject')
-rcategories.tag_relation('metadata', ('*', 'modification_date', '*'), 'subject')
-rcategories.tag_relation('metadata', ('*', 'owned_by', '*'), 'subject')
-rcategories.tag_relation('metadata', ('*', 'created_by', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'has_text', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'is', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'is', '*'), 'object')
-rcategories.tag_relation('generated', ('*', 'is_instance_of', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'is_instance_of', '*'), 'object')
-rcategories.tag_relation('generated', ('*', 'identity', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'identity', '*'), 'object')
-rcategories.tag_relation('generated', ('*', 'require_permission', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'wf_info_for', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'wf_info_for', '*'), 'object')
-rcategories.tag_relation('generated', ('*', 'for_user', '*'), 'subject')
-rcategories.tag_relation('generated', ('*', 'for_user', '*'), 'object')
+rcategories.tag_attribute('*', 'eid', 'primary')
+rcategories.tag_attribute('*', 'description', 'secondary')
+rcategories.tag_attribute('*', 'creation_date', 'metadata')
+rcategories.tag_attribute('*', 'modification_date', 'metadata')
+rcategories.tag_attribute('*', 'has_text', 'generated')
+
+rcategories.tag_relation('!*', 'in_state', '*', 'primary')
+rcategories.tag_relation('!*', 'owned_by', '*', 'metadata')
+rcategories.tag_relation('!*', 'created_by', '*', 'metadata')
+rcategories.tag_relation('!*', 'is', '*', 'generated')
+rcategories.tag_relation('*', 'is', '!*', 'generated')
+rcategories.tag_relation('!*', 'is_instance_of', '*', 'generated')
+rcategories.tag_relation('*', 'is_instance_of', '!*', 'generated')
+rcategories.tag_relation('!*', 'identity', '*', 'generated')
+rcategories.tag_relation('*', 'identity', '!*', 'generated')
+rcategories.tag_relation('!*', 'require_permission', '*', 'generated')
+rcategories.tag_relation('!*', 'wf_info_for', '*', 'generated')
+rcategories.tag_relation('*', 'wf_info_for', '!*', 'generated')
+rcategories.tag_relation('!*', 'for_user', '*', 'generated')
+rcategories.tag_relation('*', 'for_user', '!*', 'generated')
 
 # relations'field class
 rfields = RelationTags()
@@ -99,7 +101,7 @@
 # entity(ies) at the other end of the relation will be editable from the
 # form of the edited entity
 rinlined = RelationTags()
-rinlined.tag_relation(True, ('*', 'use_email', '*'), 'subject')
+rinlined.tag_relation('!*', 'use_email', '*', True)
 
 
 # set of tags of the form <action>_on_new on relations. <action> is a
@@ -112,14 +114,14 @@
 
 # 'link' / 'create' relation tags, used to control the "add entity" submenu
 rmode = RelationTags()
-rmode.tag_relation('link', ('*', 'is', '*'), 'subject')
-rmode.tag_relation('link', ('*', 'is', '*'), 'object')
-rmode.tag_relation('link', ('*', 'is_instance_of', '*'), 'subject')
-rmode.tag_relation('link', ('*', 'is_instance_of', '*'), 'object')
-rmode.tag_relation('link', ('*', 'identity', '*'), 'subject')
-rmode.tag_relation('link', ('*', 'identity', '*'), 'object')
-rmode.tag_relation('link', ('*', 'owned_by', '*'), 'subject')
-rmode.tag_relation('link', ('*', 'created_by', '*'), 'subject')
-rmode.tag_relation('link', ('*', 'require_permission', '*'), 'subject')
-rmode.tag_relation('link', ('*', 'wf_info_for', '*'), 'subject')
-rmode.tag_relation('link', ('*', 'wf_info_for', '*'), 'object')
+rmode.tag_relation('!*', 'is', '*', 'link')
+rmode.tag_relation('*', 'is', '!*', 'link')
+rmode.tag_relation('!*', 'is_instance_of', '*', 'link')
+rmode.tag_relation('*', 'is_instance_of', '!*', 'link')
+rmode.tag_relation('!*', 'identity', '*', 'link')
+rmode.tag_relation('*', 'identity', '!*', 'link')
+rmode.tag_relation('!*', 'owned_by', '*', 'link')
+rmode.tag_relation('!*', 'created_by', '*', 'link')
+rmode.tag_relation('!*', 'require_permission', '*', 'link')
+rmode.tag_relation('!*', 'wf_info_for', '*', 'link')
+rmode.tag_relation('*', 'wf_info_for', '!*', 'link')
--- a/web/views/autoform.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/autoform.py	Mon May 11 12:03:52 2009 +0200
@@ -72,7 +72,8 @@
                             category = 'secondary'
                         else:
                             category = 'generic'
-                        cls.rcategories.tag_relation(category, (X, rschema, Y), role)
+                        cls.rcategories.tag_relation(X, rschema, Y, category,
+                                                     tagged=role)
 
     @classmethod
     def erelations_by_category(cls, entity, categories=None, permission=None, rtags=None):
--- a/web/views/basecomponents.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/basecomponents.py	Mon May 11 12:03:52 2009 +0200
@@ -151,8 +151,8 @@
                                                          self.req.property_value('ui.site-title')))
 
 
-uicfg.rdisplay.tag_relation({}, ('*', 'see_also', '*'), 'subject')
-uicfg.rdisplay.tag_relation({}, ('*', 'see_also', '*'), 'object')
+uicfg.rdisplay.tag_relation('!*', 'see_also', '*', {})
+uicfg.rdisplay.tag_relation('*', 'see_also', '!*', {})
 
 class SeeAlsoVComponent(component.RelatedObjectsVComponent):
     """display any entity's see also"""
--- a/web/views/basecontrollers.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/basecontrollers.py	Mon May 11 12:03:52 2009 +0200
@@ -312,7 +312,7 @@
             view.pagination(req, rset, view.w, not view.need_navigation)
             if divid == 'pageContent':
                 stream.write(u'<div id="contentmain">')
-        view.dispatch()
+        view.render()
         extresources = req.html_headers.getvalue(skiphead=True)
         if extresources:
             stream.write(u'<div class="ajaxHtmlHead">\n') # XXX use a widget ?
@@ -349,7 +349,7 @@
             extraargs = dict((str(key), value)
                              for key, value in extraargs.items())
         extraargs = extraargs or {}
-        return comp.dispatch(**extraargs)
+        return comp.render(**extraargs)
 
     @check_pageid
     @xhtmlize
@@ -357,7 +357,7 @@
         view = self.vreg.select_view('inline-creation', self.req, None,
                                      etype=ttype, peid=peid, rtype=rtype,
                                      role=role)
-        return view.dispatch(etype=ttype, peid=peid, rtype=rtype, role=role)
+        return view.render(etype=ttype, peid=peid, rtype=rtype, role=role)
 
     @jsonize
     def js_validate_form(self, action, names, values):
--- a/web/views/basetemplates.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/basetemplates.py	Mon May 11 12:03:52 2009 +0200
@@ -89,7 +89,7 @@
             view.w(u'<?xml version="1.0"?>\n' + STRICT_DOCTYPE)
             view.w(u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">')
         # have to replace our unicode stream using view's binary stream
-        view.dispatch()
+        view.render()
         if xhtml_wrap:
             view.w(u'</div>')
         self._stream = view._stream
@@ -115,13 +115,13 @@
         etypefilter = self.vreg.select_component('etypenavigation',
                                                  self.req, self.rset)
         if etypefilter and etypefilter.propval('visible'):
-            etypefilter.dispatch(w=w)
+            etypefilter.render(w=w)
         self.nav_html = UStringIO()
         if view and view.need_navigation:
             view.paginate(w=self.nav_html.write)
         w(_(self.nav_html.getvalue()))
         w(u'<div id="contentmain">\n')
-        view.dispatch(w=w)
+        view.render(w=w)
         w(u'</div>\n') # close id=contentmain
         w(_(self.nav_html.getvalue()))
         w(u'</div>\n') # closes id=pageContent
@@ -154,10 +154,10 @@
         w(u'<td id="contentcol">\n')
         rqlcomp = self.vreg.select_component('rqlinput', self.req, self.rset)
         if rqlcomp:
-            rqlcomp.dispatch(w=self.w, view=view)
+            rqlcomp.render(w=self.w, view=view)
         msgcomp = self.vreg.select_component('applmessages', self.req, self.rset)
         if msgcomp:
-            msgcomp.dispatch(w=self.w)
+            msgcomp.render(w=self.w)
         self.content_header(view)
 
     def template_footer(self, view=None):
@@ -174,7 +174,7 @@
         if boxes:
             self.w(u'<td class="navcol"><div class="navboxes">\n')
             for box in boxes:
-                box.dispatch(w=self.w, view=view)
+                box.render(w=self.w, view=view)
             self.w(u'</div></td>\n')
 
     def content_header(self, view=None):
@@ -199,7 +199,7 @@
         view = self.vreg.select_view('error', self.req, self.rset)
         self.template_header(self.content_type, view, self.req._('an error occured'),
                              [NOINDEX, NOFOLLOW])
-        view.dispatch(w=self.w)
+        view.render(w=self.w)
         self.template_footer(view)
 
     def template_header(self, content_type, view=None, page_title='', additional_headers=()):
@@ -243,7 +243,7 @@
         if boxes:
             w(u'<div class="navboxes">\n')
             for box in boxes:
-                box.dispatch(w=w)
+                box.render(w=w)
             self.w(u'</div>\n')
         w(u'</td>')
         w(u'<td id="contentcol" rowspan="2">')
@@ -255,7 +255,7 @@
     def topleft_header(self):
         self.w(u'<table id="header"><tr>\n')
         self.w(u'<td>')
-        self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+        self.vreg.select_component('logo', self.req, self.rset).render(w=self.w)
         self.w(u'</td>\n')
         self.w(u'</tr></table>\n')
 
@@ -322,25 +322,25 @@
         """build the top menu with authentification info and the rql box"""
         self.w(u'<table id="header"><tr>\n')
         self.w(u'<td id="firstcolumn">')
-        self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+        self.vreg.select_component('logo', self.req, self.rset).render(w=self.w)
         self.w(u'</td>\n')
         # appliname and breadcrumbs
         self.w(u'<td id="headtext">')
         comp = self.vreg.select_component('appliname', self.req, self.rset)
         if comp and comp.propval('visible'):
-            comp.dispatch(w=self.w)
+            comp.render(w=self.w)
         comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
         if comp and comp.propval('visible'):
-            comp.dispatch(w=self.w, view=view)
+            comp.render(w=self.w, view=view)
         self.w(u'</td>')
         # logged user and help
         self.w(u'<td>\n')
         comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
-        comp.dispatch(w=self.w)
+        comp.render(w=self.w)
         self.w(u'</td><td>')
         helpcomp = self.vreg.select_component('help', self.req, self.rset)
         if helpcomp: # may not be available if Card is not defined in the schema
-            helpcomp.dispatch(w=self.w)
+            helpcomp.render(w=self.w)
         self.w(u'</td>')
         # lastcolumn
         self.w(u'<td id="lastcolumn">')
@@ -399,7 +399,7 @@
         if components:
             self.w(u'<div id="contentheader">')
             for comp in components:
-                comp.dispatch(w=self.w, view=view)
+                comp.render(w=self.w, view=view)
             self.w(u'</div><div class="clear"></div>')
 
 
@@ -416,7 +416,7 @@
         if components:
             self.w(u'<div id="contentfooter">')
             for comp in components:
-                comp.dispatch(w=self.w, view=view)
+                comp.render(w=self.w, view=view)
             self.w(u'</div>')
 
 
--- a/web/views/bookmark.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/bookmark.py	Mon May 11 12:03:52 2009 +0200
@@ -14,8 +14,8 @@
 from cubicweb.web import uicfg, action, box, formwidgets
 from cubicweb.web.views import primary
 
-uicfg.rcategories.tag_relation('primary', ('Bookmark', 'path', '*'), 'subject')
-uicfg.rwidgets.tag_relation(formwidgets.TextInput, ('Bookmark', 'path', '*'), 'subject')
+uicfg.rcategories.tag_attribute('!Bookmark', 'path', 'primary')
+uicfg.rwidgets.tag_attribute('Bookmark', 'path', formwidgets.TextInput)
 
 
 class FollowAction(action.Action):
--- a/web/views/boxes.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/boxes.py	Mon May 11 12:03:52 2009 +0200
@@ -64,7 +64,7 @@
                         else:
                             # link mode by default
                             mode = 'link'
-                        cls.rmode.tag_relation(mode, (X, rschema, Y), role)
+                        cls.rmode.tag_relation(X, rschema, Y, mode, tagged=role)
 
     @classmethod
     def relation_mode(cls, rtype, etype, targettype, role='subject'):
--- a/web/views/cwproperties.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/cwproperties.py	Mon May 11 12:03:52 2009 +0200
@@ -339,5 +339,5 @@
         self.widget = wdg
 
 
-uicfg.rfields.tag_relation(PropertyKeyField, ('CWProperty', 'pkey', '*'), 'subject')
-uicfg.rfields.tag_relation(PropertyValueField, ('CWProperty', 'value', '*'), 'subject')
+uicfg.rfields.tag_attribute('CWProperty', 'pkey', PropertyKeyField)
+uicfg.rfields.tag_attribute('CWProperty', 'value', PropertyValueField)
--- a/web/views/cwuser.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/cwuser.py	Mon May 11 12:03:52 2009 +0200
@@ -14,19 +14,18 @@
 from cubicweb.web.views import primary
 
 
-uicfg.rcategories.tag_relation('secondary', ('CWUser', 'firstname', '*'), 'subject')
-uicfg.rcategories.tag_relation('secondary', ('CWUser', 'surname', '*'), 'subject')
-uicfg.rcategories.tag_relation('metadata', ('CWUser', 'last_login_time', '*'), 'subject')
-uicfg.rcategories.tag_relation('primary', ('CWUser', 'in_group', '*'), 'subject')
-uicfg.rcategories.tag_relation('generated', ('*', 'owned_by', 'CWUser'), 'object')
-uicfg.rcategories.tag_relation('generated', ('*', 'created_by', 'CWUser'), 'object')
-uicfg.rcategories.tag_relation('metadata', ('*', 'bookmarked_by', 'CWUser'), 'object')
-uicfg.rmode.tag_relation('create', ('*', 'in_group', 'CWGroup'), 'object')
-uicfg.rmode.tag_relation('link', ('*', 'owned_by', 'CWUser'), 'object')
-uicfg.rmode.tag_relation('link', ('*', 'created_by', 'CWUser'), 'object')
-uicfg.rmode.tag_relation('create', ('*', 'bookmarked_by', 'CWUser'), 'object')
-uicfg.rdisplay.tag_attribute({}, 'CWUser', 'firstname')
-uicfg.rdisplay.tag_attribute({}, 'CWUser', 'surname')
+uicfg.rcategories.tag_attribute('CWUser', 'firstname', 'secondary')
+uicfg.rcategories.tag_attribute('CWUser', 'surname', 'secondary')
+uicfg.rcategories.tag_attribute('CWUser', 'last_login_time', 'metadata')
+uicfg.rcategories.tag_relation('!CWUser', 'in_group', '*', 'primary')
+uicfg.rcategories.tag_relation('*', 'owned_by', '!CWUser', 'generated')
+uicfg.rcategories.tag_relation('*', 'created_by', '!CWUser', 'generated')
+uicfg.rcategories.tag_relation('*', 'bookmarked_by', '!CWUser', 'metadata')
+
+uicfg.rmode.tag_relation('*', 'in_group', '!CWGroup', 'create')
+uicfg.rmode.tag_relation('*', 'owned_by', '!CWUser', 'link')
+uicfg.rmode.tag_relation('*', 'created_by', '!CWUser', 'link')
+uicfg.rmode.tag_relation('*', 'bookmarked_by', '!CWUser', 'create')
 
 
 class UserPreferencesEntityAction(action.Action):
@@ -77,6 +76,3 @@
         if emailaddr:
             self.w(u'<foaf:mbox>%s</foaf:mbox>\n' % html_escape(emailaddr))
         self.w(u'</foaf:Person>\n')
-
-from logilab.common.deprecation import class_renamed
-EUserPrimaryView = class_renamed('EUserPrimaryView', CWUserPrimaryView)
--- a/web/views/iprogress.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/iprogress.py	Mon May 11 12:03:52 2009 +0200
@@ -32,7 +32,7 @@
 
     header_for_COLNAME methods allow to customize header's label
     """
-    
+
     id = 'progress_table_view'
     title = _('task progression')
     __select__ = implements(IMileStone)
@@ -87,7 +87,7 @@
     def header_for_milestone(self, ecls):
         """use entity's type as label"""
         return display_name(self.req, ecls.id)
-    
+
     def table_header(self, ecls):
         """builds the table's header"""
         self.w(u'<thead><tr>')
@@ -101,7 +101,7 @@
             self.w(u'<th>%s</th>' % html_escape(colname))
         self.w(u'</tr></thead>\n')
 
-    
+
     ## cell management ########################################################
     def build_project_cell(self, entity):
         """``project`` column cell renderer"""
@@ -117,7 +117,7 @@
     def build_state_cell(self, entity):
         """``state`` column cell renderer"""
         return html_escape(self.req._(entity.state))
-    
+
     def build_eta_date_cell(self, entity):
         """``eta_date`` column cell renderer"""
         if entity.finished():
@@ -152,7 +152,7 @@
         if costdescr:
             return u'%s (%s)' % (totalcost, ', '.join(costdescr))
         return unicode(totalcost)
-    
+
     def build_progress_cell(self, entity):
         """``progress`` column cell renderer"""
         progress =  u'<div class="progress_data">%s (%.2f%%)</div>' % (
@@ -165,7 +165,7 @@
     the ``project`` column
     """
     id = 'ic_progress_table_view'
-    
+
     def call(self):
         view = self.vreg.select_view('progress_table_view', self.req, self.rset)
         columns = list(view.columns)
@@ -173,7 +173,7 @@
             columns.remove('project')
         except ValueError:
             self.info('[ic_progress_table_view] could not remove project from columns')
-        view.dispatch(w=self.w, columns=columns)
+        view.render(w=self.w, columns=columns)
 
 
 class ProgressBarView(EntityView):
--- a/web/views/navigation.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/navigation.py	Mon May 11 12:03:52 2009 +0200
@@ -153,7 +153,7 @@
     if nav:
         # get boundaries before component rendering
         start, stop = nav.page_boundaries()
-        nav.dispatch(w=w)
+        nav.render(w=w)
         params = dict(req.form)
         nav.clean_params(params)
         # make a link to see them all
--- a/web/views/primary.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/primary.py	Mon May 11 12:03:52 2009 +0200
@@ -58,8 +58,8 @@
                             where = 'sideboxes'
                         displayinfo = {'where': where,
                                        'order': cls.rdisplay.get_timestamp()}
-                        cls.rdisplay.tag_relation(displayinfo, (X, rschema, Y),
-                                                  role)
+                        cls.rdisplay.tag_relation(X, rschema, Y, displayinfo,
+                                                  tagged=role)
                     if role == 'subject':
                         displayinfo.setdefault('label', rschema.type)
                     else:
@@ -125,11 +125,11 @@
                                                 self.req, self.rset, row=self.row,
                                                 view=self, context=context):
             try:
-                comp.dispatch(w=self.w, row=self.row, view=self)
+                comp.render(w=self.w, row=self.row, view=self)
             except NotImplementedError:
                 warn('component %s doesnt implement cell_call, please update'
                      % comp.__class__, DeprecationWarning)
-                comp.dispatch(w=self.w, view=self)
+                comp.render(w=self.w, view=self)
         self.w(u'</div>')
 
     def render_entity_title(self, entity):
@@ -183,11 +183,11 @@
                 self.w(u'</div>')
             else:
                 try:
-                    box.dispatch(w=self.w, row=self.row)
+                    box.render(w=self.w, row=self.row)
                 except NotImplementedError:
                     # much probably a context insensitive box, which only implements
                     # .call() and not cell_call()
-                    box.dispatch(w=self.w)
+                    box.render(w=self.w)
 
     def _prepare_side_boxes(self, entity):
         sideboxes = []
--- a/web/views/schema.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/schema.py	Mon May 11 12:03:52 2009 +0200
@@ -19,24 +19,26 @@
 from cubicweb.web.views import TmpFileViewMixin, primary, baseviews
 
 
-uicfg.rcategories.tag_relation('primary', ('CWPermission', 'require_group', '*'), 'subject')
-uicfg.rcategories.tag_attribute('generated', 'EEtype', 'final')
-uicfg.rcategories.tag_attribute('generated', 'ERtype', 'final')
-uicfg.rinlined.tag_relation(True, ('CWRelation', 'relation_type', '*'), 'subject')
-uicfg.rinlined.tag_relation(True, ('CWRelation', 'from_entity', '*'), 'subject')
-uicfg.rinlined.tag_relation(True, ('CWRelation', 'to_entity', '*'), 'subject')
-uicfg.rwidgets.tag_attribute(formwidgets.TextInput, 'RQLExpression', 'expression')
+uicfg.rcategories.tag_relation('!CWPermission', 'require_group', '*', 'primary')
+uicfg.rcategories.tag_attribute('EEtype', 'final', 'generated')
+uicfg.rcategories.tag_attribute('ERtype', 'final', 'generated')
+
+uicfg.rinlined.tag_relation('!CWRelation', 'relation_type', '*', True)
+uicfg.rinlined.tag_relation('!CWRelation', 'from_entity', '*', True)
+uicfg.rinlined.tag_relation('!CWRelation', 'to_entity', '*', True)
 
-uicfg.rmode.tag_relation('create', ('*', 'state_of', 'CWEType'), 'object')
-uicfg.rmode.tag_relation('create', ('*', 'transition_of', 'CWEType'), 'object')
-uicfg.rmode.tag_relation('create', ('*', 'relation_type', 'CWRType'), 'object')
-uicfg.rmode.tag_relation('link', ('*', 'from_entity', 'CWEType'), 'object')
-uicfg.rmode.tag_relation('link', ('*', 'to_entity', 'CWEType'), 'object')
+uicfg.rwidgets.tag_attribute('RQLExpression', 'expression', formwidgets.TextInput)
+
+uicfg.rmode.tag_relation('*', 'state_of', '!CWEType', 'create')
+uicfg.rmode.tag_relation('*', 'transition_of', '!CWEType', 'create')
+uicfg.rmode.tag_relation('*', 'relation_type', '!CWRType', 'create')
+uicfg.rmode.tag_relation('*', 'from_entity', '!CWEType', 'link')
+uicfg.rmode.tag_relation('*', 'to_entity', '!CWEType', 'link')
 
 for attr in ('name', 'meta', 'final'):
-    uicfg.rdisplay.tag_attribute({}, 'CWRType', attr)
+    uicfg.rdisplay.tag_attribute('CWRType', attr, {})
 for attr in ('name', 'meta', 'final', 'symetric', 'inlined'):
-    uicfg.rdisplay.tag_attribute({}, 'CWRType', attr)
+    uicfg.rdisplay.tag_attribute('CWRType', attr, {})
 
 
 class ViewSchemaAction(action.Action):
--- a/web/views/startup.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/startup.py	Mon May 11 12:03:52 2009 +0200
@@ -79,7 +79,7 @@
 
     def folders(self):
         self.w(u'<h4>%s</h4>\n' % self.req._('Browse by category'))
-        self.vreg.select_view('tree', self.req, None).dispatch(w=self.w)
+        self.vreg.select_view('tree', self.req, None).render(w=self.w)
 
     def startup_views(self):
         self.w(u'<h4>%s</h4>\n' % self.req._('Startup views'))
--- a/web/views/workflow.py	Mon May 11 11:59:56 2009 +0200
+++ b/web/views/workflow.py	Mon May 11 12:03:52 2009 +0200
@@ -25,10 +25,10 @@
 
 _ = unicode
 
-EditBox.rmode.tag_relation('create', ('Transition', 'destination_state', '*'), 'subject')
-EditBox.rmode.tag_relation('create', ('*', 'allowed_transition', 'Transition'), 'object')
-EditBox.rmode.tag_relation('create', ('*', 'destination_state', 'State'), 'object')
-EditBox.rmode.tag_relation('create', ('State', 'allowed_transition', '*'), 'subject')
+EditBox.rmode.tag_relation('!Transition', 'destination_state', '*', 'create')
+EditBox.rmode.tag_relation('*', 'allowed_transition', '!Transition', 'create')
+EditBox.rmode.tag_relation('*', 'destination_state', '!State', 'create')
+EditBox.rmode.tag_relation('!State', 'allowed_transition', '*', 'create')
 
 
 # IWorkflowable views #########################################################