--- a/__init__.py Thu Aug 13 11:01:32 2009 +0200
+++ b/__init__.py Thu Aug 13 11:07:25 2009 +0200
@@ -18,7 +18,6 @@
import sys, os, logging
from StringIO import StringIO
-from urllib import quote as urlquote, unquote as urlunquote
from logilab.common.logging_ext import set_log_methods
--- a/appobject.py Thu Aug 13 11:01:32 2009 +0200
+++ b/appobject.py Thu Aug 13 11:07:25 2009 +0200
@@ -277,37 +277,13 @@
"""
cls.build___select__()
cls.vreg = registry.vreg
- cls.register_properties()
- return cls
-
- @classmethod
- def vreg_initialization_completed(cls):
- pass
-
- # properties definition:
- # key: id of the property (the actual CWProperty key is build using
- # <registry name>.<obj id>.<property id>
- # value: tuple (property type, vocabfunc, default value, property description)
- # possible types are those used by `logilab.common.configuration`
- #
- # notice that when it exists multiple objects with the same id (adaptation,
- # overriding) only the first encountered definition is considered, so those
- # objects can't try to have different default values for instance.
-
- property_defs = {}
-
- @classmethod
- def register_properties(cls):
- for propid, pdef in cls.property_defs.items():
+ pdefs = getattr(cls, 'cw_property_defs', {})
+ for propid, pdef in pdefs.items():
pdef = pdef.copy() # may be shared
pdef['default'] = getattr(cls, propid, pdef['default'])
pdef['sitewide'] = getattr(cls, 'site_wide', pdef.get('sitewide'))
- cls.vreg.register_property(cls.propkey(propid), **pdef)
-
- @classmethod
- def propkey(cls, propid):
- return '%s.%s.%s' % (cls.__registry__, cls.id, propid)
-
+ registry.vreg.register_property(cls._cwpropkey(propid), **pdef)
+ return cls
def __init__(self, req=None, rset=None, row=None, col=None, **extra):
super(AppObject, self).__init__()
@@ -317,16 +293,43 @@
self.col = col
self.extra_kwargs = extra
- def propval(self, propid):
- assert self.req
- return self.req.property_value(self.propkey(propid))
-
def view(self, __vid, rset=None, __fallback_oid=None, __registry='views',
**kwargs):
"""shortcut to self.vreg.view method avoiding to pass self.req"""
return self.vreg[__registry].render(__vid, self.req, __fallback_oid,
rset=rset, **kwargs)
+ # persistent class properties ##############################################
+ #
+ # optional `cw_property_defs` dict on a class defines available persistent
+ # properties for this class:
+ #
+ # * key: id of the property (the actual CWProperty key is build using
+ # <registry name>.<obj id>.<property id>
+ # * value: tuple (property type, vocabfunc, default value, property description)
+ # possible types are those used by `logilab.common.configuration`
+ #
+ # notice that when it exists multiple objects with the same id (adaptation,
+ # overriding) only the first encountered definition is considered, so those
+ # objects can't try to have different default values for instance.
+ #
+ # you can then access to a property value using self.propval, where self is
+ # an instance of class
+
+ @classmethod
+ def _cwpropkey(cls, propid):
+ """return cw property key for the property of the given id for this
+ class
+ """
+ return '%s.%s.%s' % (cls.__registry__, cls.id, propid)
+
+ def cw_propval(self, propid):
+ """return cw property value associated to key
+
+ <cls.__registry__>.<cls.id>.<propid>
+ """
+ return self.req.property_value(self._cwpropkey(propid))
+
# deprecated ###############################################################
@classproperty
@@ -339,15 +342,20 @@
selector = (selector,)
return selector
- @classmethod
- @deprecated('[3.5] use vreg.schema')
- def schema(cls):
- return cls.vreg.schema
+ @property
+ @deprecated('[3.5] use req.vreg')
+ def vreg(self):
+ return self.req.vreg
- @classmethod
- @deprecated('[3.5] use vreg.config')
- def schema(cls):
- return cls.vreg.config
+ @property
+ @deprecated('[3.5] use req.vreg.schema')
+ def schema(self):
+ return self.req.vreg.schema
+
+ @property
+ @deprecated('[3.5] use req.vreg.config')
+ def config(self):
+ return self.req.vreg.config
@deprecated('[3.5] use req.varmaker')
def initialize_varmaker(self):
@@ -397,4 +405,8 @@
def parse_datetime(self, value, etype='Datetime'):
return self.req.parse_datetime(value, etype)
+ @deprecated('[3.5] use self.cw_propval')
+ def propval(self, propid):
+ return self.req.property_value(self._cwpropkey(propid))
+
set_log_methods(AppObject, getLogger('cubicweb.appobject'))
--- a/common/uilib.py Thu Aug 13 11:01:32 2009 +0200
+++ b/common/uilib.py Thu Aug 13 11:07:25 2009 +0200
@@ -12,7 +12,6 @@
import csv
import re
-from urllib import quote as urlquote
from StringIO import StringIO
from logilab.mtconverter import xml_escape, html_unescape
--- a/cwvreg.py Thu Aug 13 11:01:32 2009 +0200
+++ b/cwvreg.py Thu Aug 13 11:07:25 2009 +0200
@@ -50,11 +50,7 @@
self.schema = vreg.schema
def initialization_completed(self):
- # call vreg_initialization_completed on appobjects and print
- # registry content
- for appobjects in self.itervalues():
- for appobject in appobjects:
- appobject.vreg_initialization_completed()
+ pass
@deprecated('[3.5] select object, then use obj.render()')
def render(self, __oid, req, __fallback_oid=None, rset=None, **kwargs):
@@ -143,11 +139,11 @@
assert len(objects) == 1, objects
cls = objects[0]
if cls.id == etype:
- cls.__initialize__()
+ cls.__initialize__(self.schema)
return cls
cls = dump_class(cls, etype)
cls.id = etype
- cls.__initialize__()
+ cls.__initialize__(self.schema)
return cls
VRegistry.REGISTRY_FACTORY['etypes'] = ETypeRegistry
--- a/devtools/devctl.py Thu Aug 13 11:01:32 2009 +0200
+++ b/devtools/devctl.py Thu Aug 13 11:07:25 2009 +0200
@@ -205,7 +205,7 @@
objid = '%s_%s' % (reg, obj.id)
if objid in done:
break
- if obj.property_defs:
+ if obj.cw_property_defs:
yield objid
done.add(objid)
break
--- a/entity.py Thu Aug 13 11:01:32 2009 +0200
+++ b/entity.py Thu Aug 13 11:07:25 2009 +0200
@@ -170,13 +170,13 @@
MODE_TAGS = set(('link', 'create'))
CATEGORY_TAGS = set(('primary', 'secondary', 'generic', 'generated')) # , 'metadata'))
@classmethod
- def __initialize__(cls):
+ def __initialize__(cls, schema):
"""initialize a specific entity class by adding descriptors to access
entity type's attributes and relations
"""
etype = cls.id
assert etype != 'Any', etype
- cls.e_schema = eschema = cls.schema.eschema(etype)
+ cls.e_schema = eschema = schema.eschema(etype)
for rschema, _ in eschema.attribute_definitions():
if rschema.type == 'eid':
continue
--- a/req.py Thu Aug 13 11:01:32 2009 +0200
+++ b/req.py Thu Aug 13 11:07:25 2009 +0200
@@ -7,6 +7,7 @@
"""
__docformat__ = "restructuredtext en"
+from urllib import quote as urlquote, unquote as urlunquote
from datetime import time, datetime, timedelta
from logilab.common.decorators import cached
--- a/server/hooksmanager.py Thu Aug 13 11:01:32 2009 +0200
+++ b/server/hooksmanager.py Thu Aug 13 11:07:25 2009 +0200
@@ -90,7 +90,7 @@
class.
"""
if isinstance(function_or_cls, type) and issubclass(function_or_cls, Hook):
- for event, ertype in function_or_cls.register_to():
+ for event, ertype in function_or_cls.register_to(self.schema):
for hook in self._hooks[event][ertype]:
if getattr(hook, 'im_self', None).__class__ is function_or_cls:
self._hooks[event][ertype].remove(hook)
@@ -222,7 +222,7 @@
return cls()
@classmethod
- def register_to(cls):
+ def register_to(cls, schema):
if not cls.enabled:
cls.warning('%s hook has been disabled', cls)
return
@@ -241,7 +241,7 @@
yield event, ertype
done.add((event, ertype))
try:
- eschema = cls.schema.eschema(ertype)
+ eschema = schema.eschema(ertype)
except KeyError:
# relation schema
pass
--- a/server/serverconfig.py Thu Aug 13 11:01:32 2009 +0200
+++ b/server/serverconfig.py Thu Aug 13 11:07:25 2009 +0200
@@ -263,7 +263,9 @@
except RegistryNotFound:
return hooks
for hookdef in apphookdefs:
- for event, ertype in hookdef.register_to():
+ # XXX < 3.5 bw compat
+ hookdef.__dict__['config'] = self
+ for event, ertype in hookdef.register_to(vreg.schema):
if ertype == 'Any':
ertype = ''
cb = hookdef.make_callback(event)
--- a/server/test/unittest_hooksmanager.py Thu Aug 13 11:01:32 2009 +0200
+++ b/server/test/unittest_hooksmanager.py Thu Aug 13 11:07:25 2009 +0200
@@ -170,7 +170,7 @@
class HookTC(CubicWebTC):
def test_inheritance(self):
- self.assertEquals(list(MyHook.register_to()),
+ self.assertEquals(list(MyHook.register_to(self.schema)),
zip(repeat('whatever'), ('Societe', 'Division', 'SubDivision'))
+ zip(repeat('another'), ('Societe', 'Division', 'SubDivision')))
--- a/sobjects/supervising.py Thu Aug 13 11:01:32 2009 +0200
+++ b/sobjects/supervising.py Thu Aug 13 11:07:25 2009 +0200
@@ -23,7 +23,7 @@
accepts = ('Any',)
def call(self, session, *args):
- dest = self.config['supervising-addrs']
+ dest = session.vreg.config['supervising-addrs']
if not dest: # no supervisors, don't do this for nothing...
return
self.session = session
--- a/view.py Thu Aug 13 11:01:32 2009 +0200
+++ b/view.py Thu Aug 13 11:07:25 2009 +0200
@@ -479,7 +479,6 @@
"""base class for components"""
__registry__ = 'components'
__select__ = yes()
- property_defs = {}
def div_class(self):
return '%s %s' % (self.propval('htmlclass'), self.id)
--- a/web/__init__.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/__init__.py Thu Aug 13 11:07:25 2009 +0200
@@ -13,10 +13,10 @@
from decimal import Decimal
from datetime import datetime, date, timedelta
from simplejson import dumps
+from urllib import quote as urlquote
from logilab.common.deprecation import deprecated
-from cubicweb.common.uilib import urlquote
from cubicweb.web._exceptions import *
--- a/web/action.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/action.py Thu Aug 13 11:07:25 2009 +0200
@@ -22,7 +22,7 @@
__registry__ = 'actions'
__select__ = match_search_state('normal')
- property_defs = {
+ cw_property_defs = {
'visible': dict(type='Boolean', default=True,
help=_('display the action or not')),
'order': dict(type='Int', default=99,
--- a/web/box.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/box.py Thu Aug 13 11:07:25 2009 +0200
@@ -42,7 +42,7 @@
registered = classmethod(require_group_compat(View.registered))
categories_in_order = ()
- property_defs = {
+ cw_property_defs = {
_('visible'): dict(type='Boolean', default=True,
help=_('display the box or not')),
_('order'): dict(type='Int', default=99,
--- a/web/component.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/component.py Thu Aug 13 11:07:25 2009 +0200
@@ -35,7 +35,7 @@
__select__ = one_line_rset() & primary_view() & match_context_prop()
registered = accepts_compat(has_relation_compat(condition_compat(View.registered)))
- property_defs = {
+ cw_property_defs = {
_('visible'): dict(type='Boolean', default=True,
help=_('display the component or not')),
_('order'): dict(type='Int', default=99,
@@ -63,7 +63,7 @@
id = 'navigation'
__select__ = paginated_rset()
- property_defs = {
+ cw_property_defs = {
_('visible'): dict(type='Boolean', default=True,
help=_('display the component or not')),
}
--- a/web/facet.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/facet.py Thu Aug 13 11:07:25 2009 +0200
@@ -244,7 +244,7 @@
class AbstractFacet(AppObject):
__abstract__ = True
__registry__ = 'facets'
- property_defs = {
+ cw_property_defs = {
_('visible'): dict(type='Boolean', default=True,
help=_('display the box or not')),
_('order'): dict(type='Int', default=99,
--- a/web/request.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/request.py Thu Aug 13 11:07:25 2009 +0200
@@ -89,7 +89,7 @@
self.datadir_url = self._datadir_url()
@property
- def varmaker(self)
+ def varmaker(self):
varmaker = self.get_page_data('rql_varmaker')
if varmaker is None:
varmaker = rqlvar_maker()
--- a/web/uicfg.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/uicfg.py Thu Aug 13 11:07:25 2009 +0200
@@ -69,7 +69,7 @@
from cubicweb import neg_role, onevent
from cubicweb.rtags import (RelationTags, RelationTagsBool,
- RelationTagsSet, RelationTagsDict)
+ RelationTagsSet, RelationTagsDict, register_rtag)
from cubicweb.web import formwidgets
@@ -151,12 +151,25 @@
# * 'schema'
# * 'subobject' (not displayed by default)
-indexview_etype_section = {'EmailAddress': 'subobject',
- 'CWUser': 'system',
- 'CWGroup': 'system',
- 'CWPermission': 'system',
- }
+class InitializableDict(dict):
+ def __init__(self, *args, **kwargs):
+ super(InitializableDict, self).__init__(*args, **kwargs)
+ register_rtag(self)
+ def init(self, schema, check=True):
+ for eschema in schema.entities():
+ if eschema.schema_entity():
+ self.setdefault(eschema, 'schema')
+ elif eschema.is_subobject(strict=True):
+ self.setdefault(eschema, 'subobject')
+ else:
+ self.setdefault(eschema, 'application')
+
+indexview_etype_section = InitializableDict(EmailAddress='subobject',
+ CWUser='system',
+ CWGroup='system',
+ CWPermission='system',
+ )
# autoform.AutomaticEntityForm configuration ##################################
--- a/web/views/ajaxedit.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/ajaxedit.py Thu Aug 13 11:07:25 2009 +0200
@@ -21,7 +21,7 @@
__registry__ = 'views'
__select__ = (match_form_params('rtype', 'target')
| match_kwargs('rtype', 'target'))
- property_defs = {} # don't want to inherit this from Box
+ cw_property_defs = {} # don't want to inherit this from Box
id = 'xaddrelation'
expected_kwargs = form_params = ('rtype', 'target')
--- a/web/views/basecomponents.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/basecomponents.py Thu Aug 13 11:07:25 2009 +0200
@@ -29,7 +29,7 @@
class RQLInputForm(component.Component):
"""build the rql input form, usually displayed in the header"""
id = 'rqlinput'
- property_defs = VISIBLE_PROP_DEF
+ cw_property_defs = VISIBLE_PROP_DEF
visible = False
def call(self, view=None):
@@ -59,7 +59,7 @@
class ApplLogo(component.Component):
"""build the instance logo, usually displayed in the header"""
id = 'logo'
- property_defs = VISIBLE_PROP_DEF
+ cw_property_defs = VISIBLE_PROP_DEF
# don't want user to hide this component using an cwproperty
site_wide = True
@@ -71,7 +71,7 @@
class ApplHelp(component.Component):
"""build the help button, usually displayed in the header"""
id = 'help'
- property_defs = VISIBLE_PROP_DEF
+ cw_property_defs = VISIBLE_PROP_DEF
def call(self):
self.w(u'<a href="%s" class="help" title="%s"> </a>'
% (self.build_url(_restpath='doc/main'),
@@ -82,7 +82,7 @@
"""if the user is the anonymous user, build a link to login
else a link to the connected user object with a loggout link
"""
- property_defs = VISIBLE_PROP_DEF
+ cw_property_defs = VISIBLE_PROP_DEF
# don't want user to hide this component using an cwproperty
site_wide = True
id = 'loggeduserlink'
@@ -124,7 +124,7 @@
__select__ = yes()
id = 'applmessages'
# don't want user to hide this component using an cwproperty
- property_defs = {}
+ cw_property_defs = {}
def call(self):
msgs = [msg for msg in (self.req.get_shared_data('sources_error', pop=True),
@@ -140,7 +140,7 @@
class ApplicationName(component.Component):
"""display the instance name"""
id = 'appliname'
- property_defs = VISIBLE_PROP_DEF
+ cw_property_defs = VISIBLE_PROP_DEF
# don't want user to hide this component using an cwproperty
site_wide = True
@@ -170,7 +170,7 @@
id = 'etypenavigation'
__select__ = two_etypes_rset() | match_form_params('__restrtype', '__restrtypes',
'__restrrql')
- property_defs = VISIBLE_PROP_DEF
+ cw_property_defs = VISIBLE_PROP_DEF
# don't want user to hide this component using an cwproperty
site_wide = True
visible = False # disabled by default
--- a/web/views/embedding.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/embedding.py Thu Aug 13 11:07:25 2009 +0200
@@ -12,10 +12,10 @@
import re
from urlparse import urljoin
from urllib2 import urlopen, Request, HTTPError
+from urllib import quote as urlquote # XXX should use view.url_quote method
from logilab.mtconverter import guess_encoding
-from cubicweb import urlquote # XXX should use view.url_quote method
from cubicweb.selectors import (one_line_rset, score_entity,
match_search_state, implements)
from cubicweb.interfaces import IEmbedable
--- a/web/views/startup.py Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/startup.py Thu Aug 13 11:07:25 2009 +0200
@@ -22,16 +22,6 @@
title = _('manage')
http_cache_manager = httpcache.EtagHTTPCacheManager
- @classmethod
- def vreg_initialization_completed(cls):
- for eschema in cls.schema.entities():
- if eschema.schema_entity():
- uicfg.indexview_etype_section.setdefault(eschema, 'schema')
- elif eschema.is_subobject(strict=True):
- uicfg.indexview_etype_section.setdefault(eschema, 'subobject')
- else:
- uicfg.indexview_etype_section.setdefault(eschema, 'application')
-
def display_folders(self):
return False