Commit 24ee4e34 authored by Florent Cayré's avatar Florent Cayré
Browse files

make ui configurations selectable (closes #2406609)

* introduce a new 'uicfg' registry (storing instances)

* use the relevant new APIs from lgc.registry to manage the new
  registrable uicfg objects

* cw event manager useage is gone; instead thze standard registry
  reloading mechanism is used

* ensure i18n commands still work (devctl)

* introduce dynamic uicfgs use whenever possible (various views), even
  though sometimes the classic 'static' usage remains
parent e65af61bde7d
......@@ -197,12 +197,13 @@ import sys
from os.path import join, dirname, realpath
from warnings import warn
from datetime import datetime, date, time, timedelta
from functools import partial
from logilab.common.decorators import cached, clear_cache
from logilab.common.deprecation import deprecated, class_deprecated
from logilab.common.modutils import cleanup_sys_modules
from logilab.common.registry import (
RegistryStore, Registry, classid,
RegistryStore, Registry, obj_registries,
ObjectNotFound, NoSelectableObject, RegistryNotFound)
from rql import RQLHelper
......@@ -210,13 +211,15 @@ from yams.constraints import BASE_CONVERTERS
from cubicweb import (CW_SOFTWARE_ROOT, ETYPE_NAME_MAP, CW_EVENT_MANAGER,
Binary, UnknownProperty, UnknownEid)
from cubicweb.rtags import RTAGS
from cubicweb.predicates import (implements, appobject_selectable,
_reset_is_instance_cache)
def clear_rtag_objects():
for rtag in RTAGS:
rtag.clear()
# backward compat: those modules are now refering to app objects in
# cw.web.views.uicfg and import * from backward compat. On registry reload, we
# should pop those modules from the cache so references are properly updated on
# subsequent reload
CW_EVENT_MANAGER.bind('before-registry-reload', partial(sys.modules.pop, 'cubicweb.web.uicfg', None))
CW_EVENT_MANAGER.bind('before-registry-reload', partial(sys.modules.pop, 'cubicweb.web.uihelper', None))
def use_interfaces(obj):
"""return interfaces required by the given object by searching for
......@@ -263,6 +266,15 @@ def related_appobject(obj, appobjectattr='__appobject__'):
return getattr(obj, appobjectattr, obj)
class InstancesRegistry(CWRegistry):
def selected(self, winner, args, kwargs):
"""overriden to avoid the default 'instanciation' behaviour, ie
winner(*args, **kwargs)
"""
return winner
class ETypeRegistry(CWRegistry):
def clear_caches(self):
......@@ -497,6 +509,7 @@ class CWRegistryStore(RegistryStore):
'views': ViewsRegistry,
'actions': ActionsRegistry,
'ctxcomponents': CtxComponentsRegistry,
'uicfg': InstancesRegistry,
}
def __init__(self, config, initlog=True):
......@@ -517,11 +530,6 @@ class CWRegistryStore(RegistryStore):
sys.path.remove(CW_SOFTWARE_ROOT)
self.schema = None
self.initialized = False
# XXX give force_reload (or refactor [re]loading...)
if self.config.mode != 'test':
# don't clear rtags during test, this may cause breakage with
# manually imported appobject modules
CW_EVENT_MANAGER.bind('before-registry-reload', clear_rtag_objects)
self['boxes'] = BwCompatCWRegistry(self, 'boxes', 'ctxcomponents')
self['contentnavigation'] = BwCompatCWRegistry(self, 'contentnavigation', 'ctxcomponents')
......@@ -695,8 +703,9 @@ class CWRegistryStore(RegistryStore):
or iface
for iface in ifaces)
if not ('Any' in ifaces or ifaces & implemented_interfaces):
reg = self[obj_registries(obj)[0]]
self.debug('unregister %s (no implemented '
'interface among %s)', classid(obj), ifaces)
'interface among %s)', reg.objid(obj), ifaces)
self.unregister(obj)
# since 3.9: remove appobjects which depending on other, unexistant
# appobjects
......@@ -704,8 +713,7 @@ class CWRegistryStore(RegistryStore):
try:
registry = self[regname]
except RegistryNotFound:
self.debug('unregister %s (no registry %s)', classid(obj),
regname)
self.debug('unregister %s (no registry %s)', obj, regname)
self.unregister(obj)
continue
for regid in regids:
......@@ -713,12 +721,14 @@ class CWRegistryStore(RegistryStore):
break
else:
self.debug('unregister %s (no %s object in registry %s)',
classid(obj), ' or '.join(regids), regname)
registry.objid(obj), ' or '.join(regids), regname)
self.unregister(obj)
super(CWRegistryStore, self).initialization_completed()
for rtag in RTAGS:
# don't check rtags if we don't want to cleanup_interface_sobjects
rtag.init(self.schema, check=self.config.cleanup_interface_sobjects)
if 'uicfg' in self: # 'uicfg' is not loaded in a pure repository mode
for rtags in self['uicfg'].values():
for rtag in rtags:
# don't check rtags if we don't want to cleanup_interface_sobjects
rtag.init(self.schema, check=self.config.cleanup_interface_sobjects)
# rql parsing utilities ####################################################
......
......@@ -95,11 +95,6 @@ def cleanup_sys_modules(config):
if mod.__file__.startswith(path):
del sys.modules[name]
break
# fresh rtags
from cubicweb import rtags
from cubicweb.web.views import uicfg
rtags.RTAGS[:] = []
reload(uicfg)
def generate_schema_pot(w, cubedir=None):
"""generate a pot file with schema specific i18n messages
......@@ -129,7 +124,6 @@ def generate_schema_pot(w, cubedir=None):
def _generate_schema_pot(w, vreg, schema, libconfig=None):
from copy import deepcopy
from cubicweb.i18n import add_msg
from cubicweb.web.views import uicfg
from cubicweb.schema import NO_I18NCONTEXT, CONSTRAINTS
w('# schema pot file, generated on %s\n'
% datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
......@@ -138,22 +132,21 @@ def _generate_schema_pot(w, vreg, schema, libconfig=None):
w('\n')
vregdone = set()
if libconfig is not None:
from cubicweb.cwvreg import CWRegistryStore, clear_rtag_objects
from cubicweb.cwvreg import CWRegistryStore
libschema = libconfig.load_schema(remove_unused_rtypes=False)
afs = deepcopy(uicfg.autoform_section)
appearsin_addmenu = deepcopy(uicfg.actionbox_appearsin_addmenu)
clear_rtag_objects()
afs = vreg['uicfg'].select('autoform_section')
appearsin_addmenu = vreg['uicfg'].select('actionbox_appearsin_addmenu')
cleanup_sys_modules(libconfig)
libvreg = CWRegistryStore(libconfig)
libvreg.set_schema(libschema) # trigger objects registration
libafs = uicfg.autoform_section
libappearsin_addmenu = uicfg.actionbox_appearsin_addmenu
libafs = libvreg['uicfg'].select('autoform_section')
libappearsin_addmenu = libvreg['uicfg'].select('actionbox_appearsin_addmenu')
# prefill vregdone set
list(_iter_vreg_objids(libvreg, vregdone))
else:
libschema = {}
afs = uicfg.autoform_section
appearsin_addmenu = uicfg.actionbox_appearsin_addmenu
afs = vreg['uicfg'].select('autoform_section')
appearsin_addmenu = vreg['uicfg'].select('actionbox_appearsin_addmenu')
for cstrtype in CONSTRAINTS:
add_msg(w, cstrtype)
done = set()
......
......@@ -38,17 +38,20 @@ Three primitives are defined:
__docformat__ = "restructuredtext en"
import logging
from warnings import warn
from logilab.common.logging_ext import set_log_methods
RTAGS = []
def register_rtag(rtag):
RTAGS.append(rtag)
from logilab.common.registry import RegistrableInstance, yes
def _ensure_str_key(key):
return tuple(str(k) for k in key)
class RelationTags(object):
class RegistrableRtags(RegistrableInstance):
__registry__ = 'uicfg'
__select__ = yes()
class RelationTags(RegistrableRtags):
"""a tag store for full relation definitions :
(subject type, relation type, object type, tagged)
......@@ -58,18 +61,17 @@ class RelationTags(object):
This class associates a single tag to each key.
"""
_allowed_values = None
_initfunc = None
def __init__(self, name=None, initfunc=None, allowed_values=None):
self._name = name or '<unknown>'
# _init expected to be a method (introduced in 3.17), while _initfunc a
# function given as __init__ argument and kept for bw compat
_init = _initfunc = None
def __init__(self):
self._tagdefs = {}
if allowed_values is not None:
self._allowed_values = allowed_values
if initfunc is not None:
self._initfunc = initfunc
register_rtag(self)
def __repr__(self):
return '%s: %s' % (self._name, repr(self._tagdefs))
# find a way to have more infos but keep it readable
# (in error messages in case of an ambiguity for instance)
return '%s (%s): %s' % (id(self), self.__regid__, self.__class__)
# dict compat
def __getitem__(self, key):
......@@ -100,8 +102,8 @@ class RelationTags(object):
(stype, rtype, otype, tagged), value, ertype)
self.del_rtag(stype, rtype, otype, tagged)
break
if self._initfunc is not None:
self.apply(schema, self._initfunc)
if self._init is not None:
self.apply(schema, self._init)
def apply(self, schema, func):
for eschema in schema.entities():
......@@ -113,7 +115,7 @@ class RelationTags(object):
sschema, oschema = eschema, tschema
else:
sschema, oschema = tschema, eschema
func(self, sschema, rschema, oschema, role)
func(sschema, rschema, oschema, role)
# rtag declaration api ####################################################
......@@ -250,4 +252,6 @@ class NoTargetRelationTagsDict(RelationTagsDict):
key = list(key)
key[0] = '*'
super(NoTargetRelationTagsDict, self).tag_relation(key, tag)
set_log_methods(RelationTags, logging.getLogger('cubicweb.rtags'))
......@@ -258,7 +258,7 @@ from logilab.common.decorators import classproperty, cached
from logilab.common.deprecation import deprecated, class_renamed
from logilab.common.logging_ext import set_log_methods
from logilab.common.registry import (Predicate, NotPredicate, OrPredicate,
classid, objectify_predicate, yes)
objectify_predicate, yes)
from cubicweb import RegistryNotFound, server
from cubicweb.cwvreg import CWRegistry, CWRegistryStore
......@@ -768,7 +768,7 @@ class Operation(object):
"""delegate event handling to the opertaion"""
if event == 'postcommit_event' and hasattr(self, 'commit_event'):
warn('[3.10] %s: commit_event method has been replaced by postcommit_event'
% classid(self.__class__), DeprecationWarning)
% self.__class__, DeprecationWarning)
self.commit_event() # pylint: disable=E1101
getattr(self, event)()
......
......@@ -26,7 +26,7 @@ from warnings import warn
from functools import partial
from logilab.common.deprecation import deprecated
from logilab.common.registry import classid, yes
from logilab.common.registry import yes
from logilab.mtconverter import xml_escape
from rql import nodes
......@@ -608,7 +608,7 @@ def implements_adapter_compat(iface):
if hasattr(entity, func.__name__):
warn('[3.9] %s method is deprecated, define it on a custom '
'%s for %s instead' % (func.__name__, iface,
classid(entity.__class__)),
entity.__class__),
DeprecationWarning)
member = getattr(entity, func.__name__)
if callable(member):
......
......@@ -82,7 +82,6 @@ from cubicweb.web import INTERNAL_FIELD_VALUE, ProcessFormError, eid_param, \
formwidgets as fw
from cubicweb.web.views import uicfg
class UnmodifiedField(Exception):
"""raise this when a field has not actually been edited and you want to skip
it
......@@ -466,8 +465,6 @@ class Field(object):
# attribute or relation
return True
# if it's a non final relation, we need the eids
# XXX underlying regression: getattr(ent, 'foo') used to return
# a tuple, now we get a list
if isinstance(previous_value, (list, tuple)):
# widget should return a set of untyped eids
previous_value = set(e.eid for e in previous_value)
......@@ -1164,7 +1161,7 @@ class RelationField(Field):
_AFF_KWARGS = uicfg.autoform_field_kwargs
def guess_field(eschema, rschema, role='subject', **kwargs):
def guess_field(eschema, rschema, role='subject', req=None, **kwargs):
"""This function return the most adapted field to edit the given relation
(`rschema`) where the given entity type (`eschema`) is the subject or object
(`role`).
......@@ -1212,12 +1209,16 @@ def guess_field(eschema, rschema, role='subject', **kwargs):
kwargs['max_length'] = cstr.max
return StringField(**kwargs)
if fieldclass is FileField:
if req:
aff_kwargs = req.vreg['uicfg'].select('autoform_field_kwargs', req)
else:
aff_kwargs = _AFF_KWARGS
for metadata in KNOWN_METAATTRIBUTES:
metaschema = eschema.has_metadata(rschema, metadata)
if metaschema is not None:
metakwargs = _AFF_KWARGS.etype_get(eschema, metaschema, 'subject')
metakwargs = aff_kwargs.etype_get(eschema, metaschema, 'subject')
kwargs['%s_field' % metadata] = guess_field(eschema, metaschema,
**metakwargs)
req=req, **metakwargs)
return fieldclass(**kwargs)
return RelationField.fromcardinality(card, **kwargs)
......
......@@ -35,10 +35,14 @@ def setUpModule(*args):
config.bootstrap_cubes()
schema = config.load_schema()
class GuessFieldTC(TestCase):
class GuessFieldTC(CubicWebTC):
def setUp(self):
super(GuessFieldTC, self).setUp()
self.req = self.request()
def test_state_fields(self):
title_field = guess_field(schema['State'], schema['name'])
title_field = guess_field(schema['State'], schema['name'], req=self.req)
self.assertIsInstance(title_field, StringField)
self.assertEqual(title_field.required, True)
......@@ -48,7 +52,7 @@ class GuessFieldTC(TestCase):
# self.assertEqual(synopsis_field.required, False)
# self.assertEqual(synopsis_field.help, 'an abstract for this state')
description_field = guess_field(schema['State'], schema['description'])
description_field = guess_field(schema['State'], schema['description'], req=self.req)
self.assertIsInstance(description_field, RichTextField)
self.assertEqual(description_field.required, False)
self.assertEqual(description_field.format_field, None)
......@@ -56,7 +60,8 @@ class GuessFieldTC(TestCase):
# description_format_field = guess_field(schema['State'], schema['description_format'])
# self.assertEqual(description_format_field, None)
description_format_field = guess_field(schema['State'], schema['description_format'])
description_format_field = guess_field(schema['State'], schema['description_format'],
req=self.req)
self.assertEqual(description_format_field.internationalizable, True)
self.assertEqual(description_format_field.sort, True)
......@@ -66,22 +71,22 @@ class GuessFieldTC(TestCase):
def test_cwuser_fields(self):
upassword_field = guess_field(schema['CWUser'], schema['upassword'])
upassword_field = guess_field(schema['CWUser'], schema['upassword'], req=self.req)
self.assertIsInstance(upassword_field, StringField)
self.assertIsInstance(upassword_field.widget, PasswordInput)
self.assertEqual(upassword_field.required, True)
last_login_time_field = guess_field(schema['CWUser'], schema['last_login_time'])
last_login_time_field = guess_field(schema['CWUser'], schema['last_login_time'], req=self.req)
self.assertIsInstance(last_login_time_field, DateTimeField)
self.assertEqual(last_login_time_field.required, False)
in_group_field = guess_field(schema['CWUser'], schema['in_group'])
in_group_field = guess_field(schema['CWUser'], schema['in_group'], req=self.req)
self.assertIsInstance(in_group_field, RelationField)
self.assertEqual(in_group_field.required, True)
self.assertEqual(in_group_field.role, 'subject')
self.assertEqual(in_group_field.help, 'groups grant permissions to the user')
owned_by_field = guess_field(schema['CWUser'], schema['owned_by'], 'object')
owned_by_field = guess_field(schema['CWUser'], schema['owned_by'], 'object', req=self.req)
self.assertIsInstance(owned_by_field, RelationField)
self.assertEqual(owned_by_field.required, False)
self.assertEqual(owned_by_field.role, 'object')
......@@ -95,7 +100,7 @@ class GuessFieldTC(TestCase):
# data_name_field = guess_field(schema['File'], schema['data_name'])
# self.assertEqual(data_name_field, None)
data_field = guess_field(schema['File'], schema['data'])
data_field = guess_field(schema['File'], schema['data'], req=self.req)
self.assertIsInstance(data_field, FileField)
self.assertEqual(data_field.required, True)
self.assertIsInstance(data_field.format_field, StringField)
......@@ -103,7 +108,7 @@ class GuessFieldTC(TestCase):
self.assertIsInstance(data_field.name_field, StringField)
def test_constraints_priority(self):
salesterm_field = guess_field(schema['Salesterm'], schema['reason'])
salesterm_field = guess_field(schema['Salesterm'], schema['reason'], req=self.req)
constraints = schema['reason'].rdef('Salesterm', 'String').constraints
self.assertEqual([c.__class__ for c in constraints],
[SizeConstraint, StaticVocabularyConstraint])
......@@ -112,7 +117,7 @@ class GuessFieldTC(TestCase):
def test_bool_field_base(self):
field = guess_field(schema['CWAttribute'], schema['indexed'])
field = guess_field(schema['CWAttribute'], schema['indexed'], req=self.req)
self.assertIsInstance(field, BooleanField)
self.assertEqual(field.required, False)
self.assertIsInstance(field.widget, Radio)
......@@ -121,7 +126,7 @@ class GuessFieldTC(TestCase):
def test_bool_field_explicit_choices(self):
field = guess_field(schema['CWAttribute'], schema['indexed'],
choices=[(u'maybe', '1'), (u'no', '')])
choices=[(u'maybe', '1'), (u'no', '')], req=self.req)
self.assertIsInstance(field.widget, Radio)
self.assertEqual(field.vocabulary(mock(req=mock(_=unicode))),
[(u'maybe', '1'), (u'no', '')])
......
......@@ -107,6 +107,24 @@ class DefinitionOrderTC(CubicWebTC):
self.assertEqual(afk_get('CWUser', 'firstname', 'String', 'subject'), {'order': 1})
class UicfgRegistryTC(CubicWebTC):
def test_default_uicfg_object(self):
'CW default ui config objects must be registered in uicfg registry'
onames = ('autoform_field', 'autoform_section', 'autoform_field_kwargs')
for oname in onames:
obj = self.vreg['uicfg'].select_or_none(oname)
self.assertTrue(obj is not None, '%s not found in uicfg registry'
% oname)
def test_custom_uicfg(self):
ASRT = uicfg.AutoformSectionRelationTags
custom_afs = ASRT()
custom_afs.__select__ = ASRT.__select__ & ASRT.__select__
self.vreg['uicfg'].register(custom_afs)
obj = self.vreg['uicfg'].select_or_none('autoform_section')
self.assertTrue(obj is custom_afs)
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
......
......@@ -291,7 +291,8 @@ class AddRelatedActions(action.Action):
method to return an empty list. If you only want some, you can configure
them by using uicfg.actionbox_appearsin_addmenu
"""
appearsin_addmenu = uicfg.actionbox_appearsin_addmenu
appearsin_addmenu = self._cw.vreg['uicfg'].select(
'actionbox_appearsin_addmenu', self._cw, entity=entity)
req = self._cw
eschema = entity.e_schema
for role, rschemas in (('subject', eschema.subject_relations()),
......
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -126,7 +126,6 @@ from warnings import warn
from logilab.mtconverter import xml_escape
from logilab.common.decorators import iclassmethod, cached
from logilab.common.deprecation import deprecated
from logilab.common.registry import classid
from cubicweb import typed_eid, neg_role, uilib
from cubicweb.schema import display_name
......@@ -140,9 +139,6 @@ from cubicweb.web import (stdmsgs, eid_param,
from cubicweb.web.views import uicfg, forms
from cubicweb.web.views.ajaxcontroller import ajaxfunc
_AFS = uicfg.autoform_section
_AFFK = uicfg.autoform_field_kwargs
# inlined form handling ########################################################
......@@ -755,6 +751,8 @@ class AutomaticEntityForm(forms.EntityFieldsForm):
def __init__(self, *args, **kwargs):
super(AutomaticEntityForm, self).__init__(*args, **kwargs)
self.uicfg_afs = self._cw.vreg['uicfg'].select(
'autoform_section', self._cw, entity=self.edited_entity)
entity = self.edited_entity
if entity.has_eid():
entity.complete()
......@@ -820,8 +818,8 @@ class AutomaticEntityForm(forms.EntityFieldsForm):
def _inlined_form_view_field(self, view):
# XXX allow more customization
kwargs = _AFFK.etype_get(self.edited_entity.e_schema, view.rtype,
view.role, view.etype)
kwargs = self.uicfg_affk.etype_get(self.edited_entity.e_schema,
view.rtype, view.role, view.etype)
if kwargs is None:
kwargs = {}
return InlinedFormField(view=view, **kwargs)
......@@ -832,7 +830,7 @@ class AutomaticEntityForm(forms.EntityFieldsForm):
"""return a list of (relation schema, target schemas, role) matching
given category(ies) and permission
"""
return _AFS.relations_by_section(
return self.uicfg_afs.relations_by_section(
self.edited_entity, self.formtype, section, permission, strict)
def editable_attributes(self, strict=False):
......@@ -963,6 +961,7 @@ class AutomaticEntityForm(forms.EntityFieldsForm):
## default form ui configuration ##############################################
_AFS = uicfg.autoform_section
# use primary and not generated for eid since it has to be an hidden
_AFS.tag_attribute(('*', 'eid'), 'main', 'attributes')
_AFS.tag_attribute(('*', 'eid'), 'muledit', 'attributes')
......@@ -994,6 +993,7 @@ _AFS.tag_subject_of(('CWRelation', 'relation_type', '*'), 'main', 'inlined')
_AFS.tag_subject_of(('CWRelation', 'from_entity', '*'), 'main', 'inlined')
_AFS.tag_subject_of(('CWRelation', 'to_entity', '*'), 'main', 'inlined')
_AFFK = uicfg.autoform_field_kwargs
_AFFK.tag_attribute(('RQLExpression', 'expression'),
{'widget': fw.TextInput})
_AFFK.tag_subject_of(('TrInfo', 'wf_info_for', '*'),
......
......@@ -302,9 +302,6 @@ class FieldsForm(form.Form):
return processed
_AFF = uicfg.autoform_field
_AFF_KWARGS = uicfg.autoform_field_kwargs
class EntityFieldsForm(FieldsForm):
"""This class is designed for forms used to edit some entities. It should
handle for you all the underlying stuff necessary to properly work with the
......@@ -315,6 +312,8 @@ class EntityFieldsForm(FieldsForm):
__select__ = (match_kwargs('entity')
| (one_line_rset() & non_final_entity()))
domid = 'entityForm'
uicfg_aff = uicfg.autoform_field
uicfg_affk = uicfg.autoform_field_kwargs
@iclassmethod
def field_by_name(cls_or_self, name, role=None, eschema=None):
......@@ -330,15 +329,21 @@ class EntityFieldsForm(FieldsForm):
rschema = eschema.schema.rschema(name)
# XXX use a sample target type. Document this.
tschemas = rschema.targets(eschema, role)
fieldcls = _AFF.etype_get(eschema, rschema, role, tschemas[0])
kwargs = _AFF_KWARGS.etype_get(eschema, rschema, role, tschemas[0])
fieldcls = cls_or_self.uicfg_aff.etype_get(
eschema, rschema, role, tschemas[0])
kwargs = cls_or_self.uicfg_affk.etype_get(
eschema, rschema, role, tschemas[0])
if kwargs is None:
kwargs = {}
if fieldcls:
if not isinstance(fieldcls, type):
return fieldcls # already and instance
return fieldcls(name=name, role=role, eidparam=True, **kwargs)
field = guess_field(eschema, rschema, role, eidparam=True, **kwargs)
if isinstance(cls_or_self, type):
req = None
else:
req = cls_or_self._cw
field = guess_field(eschema, rschema, role, req=req, eidparam=True, **kwargs)
if field is None:
raise
return field
......@@ -350,6 +355,10 @@ class EntityFieldsForm(FieldsForm):
self.edited_entity = rset.complete_entity(row or 0, col or 0)
msg = kwargs.pop('submitmsg', None)
super(EntityFieldsForm, self).__init__(_cw, rset, row, col, **kwargs)
self.uicfg_aff = self._cw.vreg['uicfg'].select(
'autoform_field', self._cw, entity=self.edited_entity)
self.uicfg_affk = self._cw.vreg['uicfg'].select(
'autoform_field_kwargs', self._cw, entity=self.edited_entity)
self.add_hidden('__type', self.edited_entity.__regid__, eidparam=True)
self.add_hidden('eid', self.edited_entity.eid)
# mainform default to true in parent, hence default to True
......
......@@ -76,7 +76,9 @@ class SecurityManagementView(SecurityViewMixIn, EntityView):
domid='ownership%s' % entity.eid,
__redirectvid='security',
__redirectpath=entity.rest_path())
field = guess_field(entity.e_schema, self._cw.vreg.schema.rschema('owned_by'))
field = guess_field(entity.e_schema,
self._cw.vreg.schema['owned_by'],
req=self._cw)
form.append_field(field)
form.render(w=self.w, display_progress_div=False)
......
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
......@@ -97,8 +97,8 @@ class PrimaryView(EntityView):
title = _('primary')
show_attr_label = True
show_rel_label = True
rsection = uicfg.primaryview_section
display_ctrl = uicfg.primaryview_display_ctrl
rsection = None
display_ctrl = None
main_related_section = True
def html_headers(self):
......@@ -111,6 +111,13 @@ class PrimaryView(EntityView):
def entity_call(self, entity):
entity.complete()
uicfg_reg = self._cw.vreg['uicfg']
if self.rsection is None:
self.rsection = uicfg_reg.select('primaryview_section',
self._cw, entity=entity)
if self.display_ctrl is None:
self.display_ctrl = uicfg_reg.select('primaryview_display_ctrl',
self._cw, entity=entity)
self.render_entity(entity)