merge
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 03 Aug 2009 10:53:31 +0200
changeset 2655 48cd71bdb5cd
parent 2650 18aec79ec3a3 (current diff)
parent 2654 6512522860aa (diff)
child 2656 a93ae0f6c0ad
merge
cwvreg.py
vregistry.py
web/views/primary.py
--- a/_exceptions.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/_exceptions.py	Mon Aug 03 10:53:31 2009 +0200
@@ -129,6 +129,9 @@
 class UnknownProperty(RegistryException):
     """property found in database but unknown in registry"""
 
+class RegistryOutOfDate(RegistryException):
+    """raised when a source file modification is detected"""
+
 # query exception #############################################################
 
 class QueryError(CubicWebRuntimeError):
--- a/cwconfig.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/cwconfig.py	Mon Aug 03 10:53:31 2009 +0200
@@ -777,7 +777,7 @@
             return
         self._logging_initialized = True
         CubicWebNoAppConfiguration.init_log(self, logthreshold, debug,
-                                         logfile=self.get('log-file'))
+                                            logfile=self.get('log-file'))
         # read a config file if it exists
         logconfig = join(self.apphome, 'logging.conf')
         if exists(logconfig):
--- a/cwctl.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/cwctl.py	Mon Aug 03 10:53:31 2009 +0200
@@ -382,6 +382,11 @@
           'default': None,
           'help': 'profile code and use the specified file to store stats',
           }),
+        ('loglevel',
+         {'short': 'l', 'type' : 'choice', 'metavar': '<log level>',
+          'default': None, 'choices': ('debug', 'info', 'warning', 'error'),
+          'help': 'debug if -D is set, error otherwise',
+          }),
         )
 
     def start_instance(self, appid):
@@ -390,7 +395,12 @@
         # without all options defined
         debug = self.get('debug')
         force = self.get('force')
+        loglevel = self.get('loglevel')
         config = cwcfg.config_for(appid)
+        if loglevel is not None:
+            loglevel = 'LOG_%s' % loglevel.upper()
+            config.global_set_option('log-threshold', loglevel)
+            config.init_log(loglevel, debug=debug, force=True)
         if self.get('profile'):
             config.global_set_option('profile', self.config.profile)
         helper = self.config_helper(config, cmdname='start')
@@ -399,16 +409,7 @@
             msg = "%s seems to be running. Remove %s by hand if necessary or use \
 the --force option."
             raise ExecutionError(msg % (appid, pidf))
-        command = helper.start_command(config, debug)
-        if debug:
-            print "starting server with command :"
-            print command
-        if system(command):
-            print 'an error occured while starting the instance, not started'
-            print
-            return False
-        if not debug:
-            print '-> instance %s started.' % appid
+        helper.start_command(config, debug)
         return True
 
 
--- a/cwvreg.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/cwvreg.py	Mon Aug 03 10:53:31 2009 +0200
@@ -14,7 +14,8 @@
 from rql import RQLHelper
 
 from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid,
-                      ObjectNotFound, NoSelectableObject, RegistryNotFound)
+                      ObjectNotFound, NoSelectableObject, RegistryNotFound,
+                      RegistryOutOfDate)
 from cubicweb.vregistry import VRegistry, Registry
 from cubicweb.rtags import RTAGS
 
@@ -279,6 +280,15 @@
 
     def register_objects(self, path, force_reload=None):
         """overriden to remove objects requiring a missing interface"""
+        try:
+            self._register_objects(path, force_reload)
+        except RegistryOutOfDate:
+            # modification detected, reset and reload
+            self.reset()
+            self._register_objects(path, force_reload)
+
+    def _register_objects(self, path, force_reload=None):
+        """overriden to remove objects requiring a missing interface"""
         extrapath = {}
         for cubesdir in self.config.cubes_search_path():
             if cubesdir != self.config.CUBES_DIR:
--- a/etwist/server.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/etwist/server.py	Mon Aug 03 10:53:31 2009 +0200
@@ -8,12 +8,15 @@
 __docformat__ = "restructuredtext en"
 
 import sys
+import os
 import select
 from time import mktime
 from datetime import date, timedelta
 from urlparse import urlsplit, urlunsplit
+import hotshot
 
 from twisted.application import service, strports
+from twisted.scripts._twistd_unix import daemonize
 from twisted.internet import reactor, task, threads
 from twisted.internet.defer import maybeDeferred
 from twisted.web2 import channel, http, server, iweb
@@ -268,35 +271,6 @@
             content = self.appli.need_login_content(req)
         return http.Response(code, req.headers_out, content)
 
-
-# This part gets run when you run this file via: "twistd -noy demo.py"
-def main(appid, cfgname):
-    """Starts an cubicweb  twisted server for an instance
-
-    appid: instance's identifier
-    cfgname: name of the configuration to use (twisted or all-in-one)
-    """
-    from cubicweb.cwconfig import CubicWebConfiguration
-    from cubicweb.etwist import twconfig # trigger configuration registration
-    config = CubicWebConfiguration.config_for(appid, cfgname)
-    # XXX why calling init_available_cubes here ?
-    config.init_available_cubes()
-    # create the site and application objects
-    if '-n' in sys.argv: # debug mode
-        cubicweb = CubicWebRootResource(config, debug=True)
-    else:
-        cubicweb = CubicWebRootResource(config)
-    #toplevel = vhost.VHostURIRewrite(base_url, cubicweb)
-    toplevel = cubicweb
-    website = server.Site(toplevel)
-    application = service.Application("cubicweb")
-    # serve it via standard HTTP on port set in the configuration
-    s = strports.service('tcp:%04d' % (config['port'] or 8080),
-                         channel.HTTPFactory(website))
-    s.setServiceParent(application)
-    return application
-
-
 from twisted.python import failure
 from twisted.internet import defer
 from twisted.web2 import fileupload
@@ -378,3 +352,22 @@
     ocount = sorted(ocount.items(), key=lambda x: x[1], reverse=True)[:20]
     pprint(ocount)
     print 'UNREACHABLE', gc.garbage
+
+def run(config, debug):
+    # create the site
+    root_resource = CubicWebRootResource(config, debug)
+    website = server.Site(root_resource)
+    # serve it via standard HTTP on port set in the configuration
+    port = config['port'] or 8080
+    reactor.listenTCP(port, channel.HTTPFactory(website))
+    baseurl = config['base-url'] or config.default_base_url()
+    print "-> Instance started on", baseurl
+    if not debug:
+        daemonize()
+        if config['pid-file']:
+            file(config['pid-file'], 'w').write(str(os.getpid()))
+    if config['profile']:
+        prof = hotshot.Profile(config['profile'])
+        prof.runcall(reactor.run)
+    else:
+        reactor.run()
--- a/etwist/twctl.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/etwist/twctl.py	Mon Aug 03 10:53:31 2009 +0200
@@ -10,50 +10,17 @@
 
 from cubicweb import underline_title
 from cubicweb.toolsutils import CommandHandler
-from cubicweb.web.webctl import WebCreateHandler
 
 # trigger configuration registration
 import cubicweb.etwist.twconfig # pylint: disable-msg=W0611
 
-
-class TWCreateHandler(WebCreateHandler):
-    cfgname = 'twisted'
-
-    def bootstrap(self, cubes, inputlevel=0):
-        """bootstrap this configuration"""
-        print '\n'+underline_title('Configuring Twisted')
-        mainpyfile = self.config.server_file()
-        mainpy = open(mainpyfile, 'w')
-        mainpy.write('''
-from cubicweb.etwist import server
-application = server.main(%r, %r)
-''' % (self.config.appid, self.config.name))
-        mainpy.close()
-        print '-> generated %s' % mainpyfile
-        super(TWCreateHandler, self).bootstrap(cubes, inputlevel)
-
-
 class TWStartHandler(CommandHandler):
     cmdname = 'start'
     cfgname = 'twisted'
 
     def start_command(self, config, debug):
-        command = ['%s `which twistd`' % sys.executable]
-        for ctl_opt, server_opt in (('pid-file', 'pidfile'),
-                                    ('uid', 'uid'),
-                                    ('log-file', 'logfile',)):
-            value = config[ctl_opt]
-            if not value or (debug and ctl_opt == 'log-file'):
-                continue
-            command.append('--%s %s' % (server_opt, value))
-        if debug:
-            command.append('-n')
-        if config['profile']:
-            command.append('-p %s --savestats' % config['profile'])
-        command.append('-oy')
-        command.append(self.config.server_file())
-        return ' '.join(command)
-
+        from cubicweb.etwist import server
+        server.run(config, debug)
 
 class TWStopHandler(CommandHandler):
     cmdname = 'stop'
@@ -63,7 +30,7 @@
 try:
     from cubicweb.server import serverctl
 
-    class AllInOneCreateHandler(serverctl.RepositoryCreateHandler, TWCreateHandler):
+    class AllInOneCreateHandler(serverctl.RepositoryCreateHandler):
         """configuration to get an instance running in a twisted web server
         integrating a repository server in the same process
         """
@@ -72,7 +39,6 @@
         def bootstrap(self, cubes, inputlevel=0):
             """bootstrap this configuration"""
             serverctl.RepositoryCreateHandler.bootstrap(self, cubes, inputlevel)
-            TWCreateHandler.bootstrap(self, cubes, inputlevel)
 
     class AllInOneStartHandler(TWStartHandler):
         cmdname = 'start'
--- a/vregistry.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/vregistry.py	Mon Aug 03 10:53:31 2009 +0200
@@ -31,8 +31,15 @@
 from logilab.common.deprecation import deprecated
 
 from cubicweb import CW_SOFTWARE_ROOT, set_log_methods
-from cubicweb import RegistryNotFound, ObjectNotFound, NoSelectableObject
+from cubicweb import (RegistryNotFound, ObjectNotFound, NoSelectableObject,
+                      RegistryOutOfDate)
 
+# XXX depending on cubicweb.web is ugly, we should deal with uicfg
+#     reset with a good old event / callback system
+try:
+    from cubicweb.web import uicfg
+except ImportError: # cubicweb.web not installed
+    uicfg = None
 
 def _toload_info(path, extrapath, _toload=None):
     """return a dictionary of <modname>: <modpath> and an ordered list of
@@ -282,6 +289,8 @@
     def reset(self):
         self.clear()
         self._lastmodifs = {}
+        if uicfg is not None:
+            reload(uicfg)
 
     def __getitem__(self, name):
         """return the registry (dictionary of class objects) associated to
@@ -372,7 +381,6 @@
             vname = obj.__class__.__name__
         self.debug('registered vobject %s in registry %s with id %s',
                    vname, registryname, oid)
-        # automatic reloading management
         self._loadedmods[obj.__module__]['%s.%s' % (obj.__module__, oid)] = obj
 
     def unregister(self, obj, registryname=None):
@@ -386,6 +394,9 @@
     def init_registration(self, path, extrapath=None):
         # compute list of all modules that have to be loaded
         self._toloadmods, filemods = _toload_info(path, extrapath)
+        # XXX is _loadedmods still necessary ? It seems like it's useful
+        #     to avoid loading same module twice, especially with the
+        #     _load_ancestors_then_object logic but this needs to be checked
         self._loadedmods = {}
         return filemods
 
@@ -417,7 +428,7 @@
         return change
 
     def load_file(self, filepath, modname, force_reload=False):
-        """load visual objects from a python file"""
+        """load app objects from a python file"""
         from logilab.common.modutils import load_module_from_name
         if modname in self._loadedmods:
             return
@@ -433,22 +444,12 @@
             # only load file if it was modified
             if modified_on <= self._lastmodifs[filepath]:
                 return
-            # if it was modified, unregister all exisiting objects
-            # from this module, and keep track of what was unregistered
-            unregistered = self.unregister_module_vobjects(modname)
-        else:
-            unregistered = None
+            # if it was modified, raise RegistryOutOfDate to reload everything
+            self.info('File %s changed since last visit', filepath)
+            raise RegistryOutOfDate()
         # load the module
         module = load_module_from_name(modname, use_sys=not force_reload)
         self.load_module(module)
-        # if something was unregistered, we need to update places where it was
-        # referenced
-        if unregistered:
-            # oldnew_mapping = {}
-            registered = self._loadedmods[modname]
-            oldnew_mapping = dict((unregistered[name], registered[name])
-                                  for name in unregistered if name in registered)
-            self.update_registered_subclasses(oldnew_mapping)
         self._lastmodifs[filepath] = modified_on
         return True
 
@@ -510,68 +511,6 @@
             return
         self.register(cls)
 
-    def unregister_module_vobjects(self, modname):
-        """removes registered objects coming from a given module
-
-        returns a dictionnary classid/class of all classes that will need
-        to be updated after reload (i.e. vobjects referencing classes defined
-        in the <modname> module)
-        """
-        unregistered = {}
-        # browse each registered object
-        for registry, objdict in self.items():
-            for oid, objects in objdict.items():
-                for obj in objects[:]:
-                    objname = obj.classid()
-                    # if the vobject is defined in this module, remove it
-                    if objname.startswith(modname):
-                        unregistered[objname] = obj
-                        objects.remove(obj)
-                        self.debug('unregistering %s in %s registry',
-                                  objname, registry)
-                    # if not, check if the vobject can be found in baseclasses
-                    # (because we also want subclasses to be updated)
-                    else:
-                        if not isinstance(obj, type):
-                            obj = obj.__class__
-                        for baseclass in obj.__bases__:
-                            if hasattr(baseclass, 'classid'):
-                                baseclassid = baseclass.classid()
-                                if baseclassid.startswith(modname):
-                                    unregistered[baseclassid] = baseclass
-                # update oid entry
-                if objects:
-                    objdict[oid] = objects
-                else:
-                    del objdict[oid]
-        return unregistered
-
-    def update_registered_subclasses(self, oldnew_mapping):
-        """updates subclasses of re-registered vobjects
-
-        if baseviews.PrimaryView is changed, baseviews.py will be reloaded
-        automatically and the new version of PrimaryView will be registered.
-        But all existing subclasses must also be notified of this change, and
-        that's what this method does
-
-        :param oldnew_mapping: a dict mapping old version of a class to
-                               the new version
-        """
-        # browse each registered object
-        for objdict in self.values():
-            for objects in objdict.values():
-                for obj in objects:
-                    if not isinstance(obj, type):
-                        obj = obj.__class__
-                    # build new baseclasses tuple
-                    newbases = tuple(oldnew_mapping.get(baseclass, baseclass)
-                                     for baseclass in obj.__bases__)
-                    # update obj's baseclasses tuple (__bases__) if needed
-                    if newbases != obj.__bases__:
-                        self.debug('updating %s.%s base classes',
-                                  obj.__module__, obj.__name__)
-                        obj.__bases__ = newbases
-
 # init logging
 set_log_methods(VObject, getLogger('cubicweb.appobject'))
 set_log_methods(VRegistry, getLogger('cubicweb.vreg'))
--- a/web/uicfg.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/web/uicfg.py	Mon Aug 03 10:53:31 2009 +0200
@@ -102,21 +102,6 @@
                                    init_primaryview_section,
                                    frozenset(('attributes', 'relations',
                                                'sideboxes', 'hidden')))
-for rtype in ('eid', 'creation_date', 'modification_date', 'cwuri',
-              'is', 'is_instance_of', 'identity',
-              'owned_by', 'created_by',
-              'in_state', 'wf_info_for', 'require_permission',
-              'from_entity', 'to_entity',
-              'see_also'):
-    primaryview_section.tag_subject_of(('*', rtype, '*'), 'hidden')
-    primaryview_section.tag_object_of(('*', rtype, '*'), 'hidden')
-primaryview_section.tag_subject_of(('*', 'use_email', '*'), 'attributes')
-primaryview_section.tag_subject_of(('*', 'primary_email', '*'), 'hidden')
-
-for attr in ('name', 'final'):
-    primaryview_section.tag_attribute(('CWEType', attr), 'hidden')
-for attr in ('name', 'final', 'symetric', 'inlined'):
-    primaryview_section.tag_attribute(('CWRType', attr), 'hidden')
 
 
 class DisplayCtrlRelationTags(RelationTagsDict):
@@ -201,62 +186,17 @@
 autoform_section = RelationTags('autoform_section', init_autoform_section,
                                 set(('primary', 'secondary', 'generic',
                                      'metadata', 'generated')))
-# use primary and not generated for eid since it has to be an hidden
-autoform_section.tag_attribute(('*', 'eid'), 'primary')
-autoform_section.tag_attribute(('*', 'description'), 'secondary')
-autoform_section.tag_attribute(('*', 'creation_date'), 'metadata')
-autoform_section.tag_attribute(('*', 'modification_date'), 'metadata')
-autoform_section.tag_attribute(('*', 'cwuri'), 'metadata')
-autoform_section.tag_attribute(('*', 'has_text'), 'generated')
-autoform_section.tag_subject_of(('*', 'in_state', '*'), 'primary')
-autoform_section.tag_subject_of(('*', 'owned_by', '*'), 'metadata')
-autoform_section.tag_subject_of(('*', 'created_by', '*'), 'metadata')
-autoform_section.tag_subject_of(('*', 'is', '*'), 'generated')
-autoform_section.tag_object_of(('*', 'is', '*'), 'generated')
-autoform_section.tag_subject_of(('*', 'is_instance_of', '*'), 'generated')
-autoform_section.tag_object_of(('*', 'is_instance_of', '*'), 'generated')
-autoform_section.tag_subject_of(('*', 'identity', '*'), 'generated')
-autoform_section.tag_object_of(('*', 'identity', '*'), 'generated')
-autoform_section.tag_subject_of(('*', 'require_permission', '*'), 'generated')
-autoform_section.tag_subject_of(('*', 'wf_info_for', '*'), 'generated')
-autoform_section.tag_object_of(('*', 'wf_info_for', '*'), 'generated')
-autoform_section.tag_subject_of(('*', 'for_user', '*'), 'generated')
-autoform_section.tag_object_of(('*', 'for_user', '*'), 'generated')
-autoform_section.tag_subject_of(('CWPermission', 'require_group', '*'), 'primary')
-autoform_section.tag_attribute(('CWEType', 'final'), 'generated')
-autoform_section.tag_attribute(('CWRType', 'final'), 'generated')
-autoform_section.tag_attribute(('CWUser', 'firstname'), 'secondary')
-autoform_section.tag_attribute(('CWUser', 'surname'), 'secondary')
-autoform_section.tag_attribute(('CWUser', 'last_login_time'), 'metadata')
-autoform_section.tag_subject_of(('CWUser', 'in_group', '*'), 'primary')
-autoform_section.tag_object_of(('*', 'owned_by', 'CWUser'), 'generated')
-autoform_section.tag_object_of(('*', 'created_by', 'CWUser'), 'generated')
-autoform_section.tag_object_of(('*', 'bookmarked_by', 'CWUser'), 'metadata')
-autoform_section.tag_attribute(('Bookmark', 'path'), 'primary')
-autoform_section.tag_subject_of(('*', 'use_email', '*'), 'generated') # inlined actually
-autoform_section.tag_subject_of(('*', 'primary_email', '*'), 'generic')
-
 
 # relations'field class
 autoform_field = RelationTags('autoform_field')
 
 # relations'field explicit kwargs (given to field's __init__)
 autoform_field_kwargs = RelationTagsDict()
-autoform_field_kwargs.tag_attribute(('RQLExpression', 'expression'),
-                                    {'widget': formwidgets.TextInput})
-autoform_field_kwargs.tag_attribute(('Bookmark', 'path'),
-                                    {'widget': formwidgets.TextInput})
-
-
 
 # inlined view flag for non final relations: when True for an entry, the
 # entity(ies) at the other end of the relation will be editable from the
 # form of the edited entity
 autoform_is_inlined = RelationTagsBool('autoform_is_inlined')
-autoform_is_inlined.tag_subject_of(('*', 'use_email', '*'), True)
-autoform_is_inlined.tag_subject_of(('CWRelation', 'relation_type', '*'), True)
-autoform_is_inlined.tag_subject_of(('CWRelation', 'from_entity', '*'), True)
-autoform_is_inlined.tag_subject_of(('CWRelation', 'to_entity', '*'), True)
 
 
 # set of tags of the form <action>_on_new on relations. <action> is a
@@ -277,28 +217,4 @@
 
 actionbox_appearsin_addmenu = RelationTagsBool('actionbox_appearsin_addmenu',
                                                init_actionbox_appearsin_addmenu)
-actionbox_appearsin_addmenu.tag_subject_of(('*', 'is', '*'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'is', '*'), False)
-actionbox_appearsin_addmenu.tag_subject_of(('*', 'is_instance_of', '*'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'is_instance_of', '*'), False)
-actionbox_appearsin_addmenu.tag_subject_of(('*', 'identity', '*'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'identity', '*'), False)
-actionbox_appearsin_addmenu.tag_subject_of(('*', 'owned_by', '*'), False)
-actionbox_appearsin_addmenu.tag_subject_of(('*', 'created_by', '*'), False)
-actionbox_appearsin_addmenu.tag_subject_of(('*', 'require_permission', '*'), False)
-actionbox_appearsin_addmenu.tag_subject_of(('*', 'wf_info_for', '*'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'wf_info_for', '*'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'state_of', 'CWEType'), True)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'transition_of', 'CWEType'), True)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'relation_type', 'CWRType'), True)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'from_entity', 'CWEType'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'to_entity', 'CWEType'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'in_group', 'CWGroup'), True)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'owned_by', 'CWUser'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'created_by', 'CWUser'), False)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'bookmarked_by', 'CWUser'), True)
-actionbox_appearsin_addmenu.tag_subject_of(('Transition', 'destination_state', '*'), True)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'allowed_transition', 'Transition'), True)
-actionbox_appearsin_addmenu.tag_object_of(('*', 'destination_state', 'State'), True)
-actionbox_appearsin_addmenu.tag_subject_of(('State', 'allowed_transition', '*'), True)
 
--- a/web/views/actions.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/web/views/actions.py	Mon Aug 03 10:53:31 2009 +0200
@@ -15,6 +15,7 @@
     authenticated_user, match_user_groups, match_search_state,
     has_permission, has_add_permission,
     )
+from cubicweb.web import uicfg
 from cubicweb.web.action import Action
 from cubicweb.web.views import linksearch_select_url, vid_from_rset
 from cubicweb.web.views.autoform import AutomaticEntityForm
@@ -297,3 +298,30 @@
 from cubicweb.web.views.bookmark import FollowAction
 FollowAction = class_moved(FollowAction)
 
+## default actions ui configuration ###########################################
+
+addmenu = uicfg.actionbox_appearsin_addmenu
+addmenu.tag_subject_of(('*', 'is', '*'), False)
+addmenu.tag_object_of(('*', 'is', '*'), False)
+addmenu.tag_subject_of(('*', 'is_instance_of', '*'), False)
+addmenu.tag_object_of(('*', 'is_instance_of', '*'), False)
+addmenu.tag_subject_of(('*', 'identity', '*'), False)
+addmenu.tag_object_of(('*', 'identity', '*'), False)
+addmenu.tag_subject_of(('*', 'owned_by', '*'), False)
+addmenu.tag_subject_of(('*', 'created_by', '*'), False)
+addmenu.tag_subject_of(('*', 'require_permission', '*'), False)
+addmenu.tag_subject_of(('*', 'wf_info_for', '*'), False)
+addmenu.tag_object_of(('*', 'wf_info_for', '*'), False)
+addmenu.tag_object_of(('*', 'state_of', 'CWEType'), True)
+addmenu.tag_object_of(('*', 'transition_of', 'CWEType'), True)
+addmenu.tag_object_of(('*', 'relation_type', 'CWRType'), True)
+addmenu.tag_object_of(('*', 'from_entity', 'CWEType'), False)
+addmenu.tag_object_of(('*', 'to_entity', 'CWEType'), False)
+addmenu.tag_object_of(('*', 'in_group', 'CWGroup'), True)
+addmenu.tag_object_of(('*', 'owned_by', 'CWUser'), False)
+addmenu.tag_object_of(('*', 'created_by', 'CWUser'), False)
+addmenu.tag_object_of(('*', 'bookmarked_by', 'CWUser'), True)
+addmenu.tag_subject_of(('Transition', 'destination_state', '*'), True)
+addmenu.tag_object_of(('*', 'allowed_transition', 'Transition'), True)
+addmenu.tag_object_of(('*', 'destination_state', 'State'), True)
+addmenu.tag_subject_of(('State', 'allowed_transition', '*'), True)
--- a/web/views/autoform.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/web/views/autoform.py	Mon Aug 03 10:53:31 2009 +0200
@@ -14,7 +14,7 @@
 from cubicweb.web import stdmsgs, uicfg
 from cubicweb.web.form import FieldNotFound
 from cubicweb.web.formfields import guess_field
-from cubicweb.web.formwidgets import Button, SubmitButton
+from cubicweb.web import formwidgets
 from cubicweb.web.views import forms, editforms
 
 
@@ -33,9 +33,9 @@
     cwtarget = 'eformframe'
     cssclass = 'entityForm'
     copy_nav_params = True
-    form_buttons = [SubmitButton(),
-                    Button(stdmsgs.BUTTON_APPLY, cwaction='apply'),
-                    Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
+    form_buttons = [formwidgets.SubmitButton(),
+                    formwidgets.Button(stdmsgs.BUTTON_APPLY, cwaction='apply'),
+                    formwidgets.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
     attrcategories = ('primary', 'secondary')
     # class attributes below are actually stored in the uicfg module since we
     # don't want them to be reloaded
@@ -307,3 +307,51 @@
 def etype_relation_field(etype, rtype, role='subject'):
     eschema = AutomaticEntityForm.schema.eschema(etype)
     return AutomaticEntityForm.field_by_name(rtype, role, eschema)
+
+
+## default form ui configuration ##############################################
+
+# use primary and not generated for eid since it has to be an hidden
+uicfg.autoform_section.tag_attribute(('*', 'eid'), 'primary')
+uicfg.autoform_section.tag_attribute(('*', 'description'), 'secondary')
+uicfg.autoform_section.tag_attribute(('*', 'creation_date'), 'metadata')
+uicfg.autoform_section.tag_attribute(('*', 'modification_date'), 'metadata')
+uicfg.autoform_section.tag_attribute(('*', 'cwuri'), 'metadata')
+uicfg.autoform_section.tag_attribute(('*', 'has_text'), 'generated')
+uicfg.autoform_section.tag_subject_of(('*', 'in_state', '*'), 'primary')
+uicfg.autoform_section.tag_subject_of(('*', 'owned_by', '*'), 'metadata')
+uicfg.autoform_section.tag_subject_of(('*', 'created_by', '*'), 'metadata')
+uicfg.autoform_section.tag_subject_of(('*', 'is', '*'), 'generated')
+uicfg.autoform_section.tag_object_of(('*', 'is', '*'), 'generated')
+uicfg.autoform_section.tag_subject_of(('*', 'is_instance_of', '*'), 'generated')
+uicfg.autoform_section.tag_object_of(('*', 'is_instance_of', '*'), 'generated')
+uicfg.autoform_section.tag_subject_of(('*', 'identity', '*'), 'generated')
+uicfg.autoform_section.tag_object_of(('*', 'identity', '*'), 'generated')
+uicfg.autoform_section.tag_subject_of(('*', 'require_permission', '*'), 'generated')
+uicfg.autoform_section.tag_subject_of(('*', 'wf_info_for', '*'), 'generated')
+uicfg.autoform_section.tag_object_of(('*', 'wf_info_for', '*'), 'generated')
+uicfg.autoform_section.tag_subject_of(('*', 'for_user', '*'), 'generated')
+uicfg.autoform_section.tag_object_of(('*', 'for_user', '*'), 'generated')
+uicfg.autoform_section.tag_subject_of(('CWPermission', 'require_group', '*'), 'primary')
+uicfg.autoform_section.tag_attribute(('CWEType', 'final'), 'generated')
+uicfg.autoform_section.tag_attribute(('CWRType', 'final'), 'generated')
+uicfg.autoform_section.tag_attribute(('CWUser', 'firstname'), 'secondary')
+uicfg.autoform_section.tag_attribute(('CWUser', 'surname'), 'secondary')
+uicfg.autoform_section.tag_attribute(('CWUser', 'last_login_time'), 'metadata')
+uicfg.autoform_section.tag_subject_of(('CWUser', 'in_group', '*'), 'primary')
+uicfg.autoform_section.tag_object_of(('*', 'owned_by', 'CWUser'), 'generated')
+uicfg.autoform_section.tag_object_of(('*', 'created_by', 'CWUser'), 'generated')
+uicfg.autoform_section.tag_object_of(('*', 'bookmarked_by', 'CWUser'), 'metadata')
+uicfg.autoform_section.tag_attribute(('Bookmark', 'path'), 'primary')
+uicfg.autoform_section.tag_subject_of(('*', 'use_email', '*'), 'generated') # inlined actually
+uicfg.autoform_section.tag_subject_of(('*', 'primary_email', '*'), 'generic')
+
+uicfg.autoform_field_kwargs.tag_attribute(('RQLExpression', 'expression'),
+                                          {'widget': formwidgets.TextInput})
+uicfg.autoform_field_kwargs.tag_attribute(('Bookmark', 'path'),
+                                          {'widget': formwidgets.TextInput})
+
+uicfg.autoform_is_inlined.tag_subject_of(('*', 'use_email', '*'), True)
+uicfg.autoform_is_inlined.tag_subject_of(('CWRelation', 'relation_type', '*'), True)
+uicfg.autoform_is_inlined.tag_subject_of(('CWRelation', 'from_entity', '*'), True)
+uicfg.autoform_is_inlined.tag_subject_of(('CWRelation', 'to_entity', '*'), True)
--- a/web/views/primary.py	Mon Aug 03 10:50:57 2009 +0200
+++ b/web/views/primary.py	Mon Aug 03 10:53:31 2009 +0200
@@ -224,3 +224,21 @@
             self.w(u'[<a href="%s">%s</a>]' % (self.build_url(rql=rql),
                                                self.req._('see them all')))
             self.w(u'</div>')
+
+## default primary ui configuration ###########################################
+
+for rtype in ('eid', 'creation_date', 'modification_date', 'cwuri',
+              'is', 'is_instance_of', 'identity',
+              'owned_by', 'created_by',
+              'in_state', 'wf_info_for', 'require_permission',
+              'from_entity', 'to_entity',
+              'see_also'):
+    uicfg.primaryview_section.tag_subject_of(('*', rtype, '*'), 'hidden')
+    uicfg.primaryview_section.tag_object_of(('*', rtype, '*'), 'hidden')
+uicfg.primaryview_section.tag_subject_of(('*', 'use_email', '*'), 'attributes')
+uicfg.primaryview_section.tag_subject_of(('*', 'primary_email', '*'), 'hidden')
+
+for attr in ('name', 'final'):
+    uicfg.primaryview_section.tag_attribute(('CWEType', attr), 'hidden')
+for attr in ('name', 'final', 'symetric', 'inlined'):
+    uicfg.primaryview_section.tag_attribute(('CWRType', attr), 'hidden')