--- a/__init__.py Thu Jul 02 10:30:44 2009 +0200
+++ b/__init__.py Thu Jul 02 10:35:03 2009 +0200
@@ -109,11 +109,16 @@
# url generation methods ##################################################
- def build_url(self, method, base_url=None, **kwargs):
+ def build_url(self, *args, **kwargs):
"""return an absolute URL using params dictionary key/values as URL
parameters. Values are automatically URL quoted, and the
publishing method to use may be specified or will be guessed.
"""
+ # use *args since we don't want first argument to be "anonymous" to
+ # avoid potential clash with kwargs
+ assert len(args) == 1, 'only 0 or 1 non-named-argument expected'
+ method = args[0]
+ base_url = kwargs.pop('base_url', None)
if base_url is None:
base_url = self.base_url()
if '_restpath' in kwargs:
--- a/appobject.py Thu Jul 02 10:30:44 2009 +0200
+++ b/appobject.py Thu Jul 02 10:35:03 2009 +0200
@@ -151,7 +151,8 @@
# try to get page boundaries from the navigation component
# XXX we should probably not have a ref to this component here (eg in
# cubicweb.common)
- nav = self.vreg.select_component('navigation', self.req, self.rset)
+ nav = self.vreg.select_object('components', 'navigation', self.req,
+ rset=self.rset)
if nav:
start, stop = nav.page_boundaries()
rql = self._limit_offset_rql(stop - start, start)
@@ -189,7 +190,8 @@
def view(self, __vid, rset=None, __fallback_vid=None, **kwargs):
"""shortcut to self.vreg.view method avoiding to pass self.req"""
- return self.vreg.view(__vid, self.req, rset, __fallback_vid, **kwargs)
+ return self.vreg.render(__vid, self.req, __fallback_vid, rset=rset,
+ **kwargs)
def initialize_varmaker(self):
varmaker = self.req.get_page_data('rql_varmaker')
@@ -202,11 +204,18 @@
controller = 'view'
- def build_url(self, method=None, **kwargs):
+ def build_url(self, *args, **kwargs):
"""return an absolute URL using params dictionary key/values as URL
parameters. Values are automatically URL quoted, and the
publishing method to use may be specified or will be guessed.
"""
+ # use *args since we don't want first argument to be "anonymous" to
+ # avoid potential clash with kwargs
+ if args:
+ assert len(args) == 1, 'only 0 or 1 non-named-argument expected'
+ method = args[0]
+ else:
+ method = None
# XXX I (adim) think that if method is passed explicitly, we should
# not try to process it and directly call req.build_url()
if method is None:
--- a/common/mixins.py Thu Jul 02 10:30:44 2009 +0200
+++ b/common/mixins.py Thu Jul 02 10:35:03 2009 +0200
@@ -244,7 +244,7 @@
@obsolete('use EntityFieldsForm.subject_in_state_vocabulary')
def subject_in_state_vocabulary(self, rschema, limit=None):
- form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
+ form = self.vreg.select('forms', 'edition', self.req, entity=self)
return form.subject_in_state_vocabulary(rschema, limit)
--- a/cwvreg.py Thu Jul 02 10:30:44 2009 +0200
+++ b/cwvreg.py Thu Jul 02 10:35:03 2009 +0200
@@ -9,6 +9,7 @@
_ = unicode
from logilab.common.decorators import cached, clear_cache
+from logilab.common.deprecation import obsolete
from rql import RQLHelper
@@ -39,7 +40,26 @@
class CubicWebRegistry(VRegistry):
- """extend the generic VRegistry with some cubicweb specific stuff"""
+ """Central registry for the cubicweb application, extending the generic
+ VRegistry with some cubicweb specific stuff.
+
+ This is one of the central object in cubicweb application, coupling
+ dynamically loaded objects with the schema and the configuration objects.
+
+ It specializes the VRegistry by adding some convenience methods to access to
+ stored objects. Currently we have the following registries of objects known
+ by the web application (library may use some others additional registries):
+
+ * etypes
+ * views
+ * components
+ * actions
+ * forms
+ * formrenderers
+ * controllers, which are directly plugged into the application
+ object to handle request publishing XXX to merge with views
+ * contentnavigation XXX to merge with components? to kill?
+ """
def __init__(self, config, debug=None, initlog=True):
if initlog:
@@ -170,7 +190,7 @@
"""
etype = str(etype)
if etype == 'Any':
- return self.select(self.registry_objects('etypes', 'Any'), 'Any')
+ return self.select('etypes', 'Any', 'Any')
eschema = self.schema.eschema(etype)
baseschemas = [eschema] + eschema.ancestors()
# browse ancestors from most specific to most generic and
@@ -181,42 +201,47 @@
except KeyError:
btype = str(baseschema)
try:
- cls = self.select(self.registry_objects('etypes', btype), etype)
+ cls = self.select('etypes', btype, etype)
break
except ObjectNotFound:
pass
else:
# no entity class for any of the ancestors, fallback to the default
# one
- cls = self.select(self.registry_objects('etypes', 'Any'), etype)
+ cls = self.select('etypes', 'Any', etype)
return cls
- def render(self, registry, oid, req, **context):
- """select an object in a given registry and render it
-
- - registry: the registry's name
- - oid : the view to call
- - req : the HTTP request
+ def render(self, __oid, req, __fallback_oid=None, __registry='views',
+ rset=None, **kwargs):
+ """select object, or fallback object if specified and the first one
+ isn't selectable, then render it
"""
- objclss = self.registry_objects(registry, oid)
try:
- rset = context.pop('rset')
- except KeyError:
- rset = None
- selected = self.select(objclss, req, rset, **context)
- return selected.render(**context)
+ obj = self.select(__registry, __oid, req, rset=rset, **kwargs)
+ except NoSelectableObject:
+ if __fallback_oid is None:
+ raise
+ obj = self.select(__registry, __fallback_oid, req, rset=rset,
+ **kwargs)
+ return obj.render(**kwargs)
def main_template(self, req, oid='main-template', **context):
"""display query by calling the given template (default to main),
and returning the output as a string instead of requiring the [w]rite
method as argument
"""
- res = self.render('views', oid, req, **context)
+ res = self.render(oid, req, **context)
if isinstance(res, unicode):
return res.encode(req.encoding)
assert isinstance(res, str)
return res
+ def select_vobject(self, registry, oid, *args, **kwargs):
+ selected = self.select_object(registry, oid, *args, **kwargs)
+ if selected and selected.propval('visible'):
+ return selected
+ return None
+
def possible_vobjects(self, registry, *args, **kwargs):
"""return an ordered list of possible app objects in a given registry,
supposing they support the 'visible' and 'order' properties (as most
@@ -226,9 +251,9 @@
key=lambda x: x.propval('order'))
if x.propval('visible')]
- def possible_actions(self, req, rset, **kwargs):
+ def possible_actions(self, req, rset=None, **kwargs):
if rset is None:
- actions = self.possible_vobjects('actions', req, rset, **kwargs)
+ actions = self.possible_vobjects('actions', req, rset=rset, **kwargs)
else:
actions = rset.possible_actions(**kwargs) # cached implementation
result = {}
@@ -236,7 +261,7 @@
result.setdefault(action.category, []).append(action)
return result
- def possible_views(self, req, rset, **kwargs):
+ def possible_views(self, req, rset=None, **kwargs):
"""return an iterator on possible views for this result set
views returned are classes, not instances
@@ -245,50 +270,34 @@
if vid[0] == '_':
continue
try:
- view = self.select(views, req, rset, **kwargs)
+ view = self.select_best(views, req, rset=rset, **kwargs)
if view.linkable():
yield view
except NoSelectableObject:
continue
except Exception:
- self.exception('error while trying to list possible %s views for %s',
+ self.exception('error while trying to select %s view for %s',
vid, rset)
- def view(self, __vid, req, rset=None, __fallback_vid=None, **kwargs):
- """shortcut to self.vreg.render method avoiding to pass self.req"""
- try:
- view = self.select_view(__vid, req, rset, **kwargs)
- except NoSelectableObject:
- if __fallback_vid is None:
- raise
- view = self.select_view(__fallback_vid, req, rset, **kwargs)
- return view.render(**kwargs)
-
+ @obsolete("use .select_object('boxes', ...)")
def select_box(self, oid, *args, **kwargs):
"""return the most specific view according to the result set"""
- try:
- return self.select_object('boxes', oid, *args, **kwargs)
- except NoSelectableObject:
- return
+ return self.select_object('boxes', oid, *args, **kwargs)
+ @obsolete("use .select_object('components', ...)")
+ def select_component(self, cid, *args, **kwargs):
+ """return the most specific component according to the result set"""
+ return self.select_object('components', cid, *args, **kwargs)
+
+ @obsolete("use .select_object('actions', ...)")
def select_action(self, oid, *args, **kwargs):
"""return the most specific view according to the result set"""
- try:
- return self.select_object('actions', oid, *args, **kwargs)
- except NoSelectableObject:
- return
+ return self.select_object('actions', oid, *args, **kwargs)
- def select_component(self, cid, *args, **kwargs):
- """return the most specific component according to the result set"""
- try:
- return self.select_object('components', cid, *args, **kwargs)
- except (NoSelectableObject, ObjectNotFound):
- return
-
+ @obsolete("use .select('views', ...)")
def select_view(self, __vid, req, rset=None, **kwargs):
"""return the most specific view according to the result set"""
- views = self.registry_objects('views', __vid)
- return self.select(views, req, rset, **kwargs)
+ return self.select('views', __vid, req, rset=rset, **kwargs)
# properties handling #####################################################
@@ -383,7 +392,7 @@
"""special registry to be used when an application has to deal with
connections to differents repository. This class add some additional wrapper
trying to hide buggy class attributes since classes are not designed to be
- shared.
+ shared among multiple registries.
"""
def etype_class(self, etype):
"""return an entity class for the given entity type.
@@ -396,25 +405,27 @@
usercls.e_schema = self.schema.eschema(etype)
return usercls
- def select(self, vobjects, *args, **kwargs):
+ def select_best(self, vobjects, *args, **kwargs):
"""return an instance of the most specific object according
to parameters
raise NoSelectableObject if not object apply
"""
- for vobject in vobjects:
- vobject.vreg = self
- vobject.schema = self.schema
- vobject.config = self.config
- selected = super(MulCnxCubicWebRegistry, self).select(vobjects, *args,
- **kwargs)
+ for vobjectcls in vobjects:
+ self._fix_cls_attrs(vobjectcls)
+ selected = super(MulCnxCubicWebRegistry, self).select_best(
+ vobjects, *args, **kwargs)
# redo the same thing on the instance so it won't use equivalent class
# attributes (which may change)
- selected.vreg = self
- selected.schema = self.schema
- selected.config = self.config
+ self._fix_cls_attrs(selected)
return selected
+ def _fix_cls_attrs(self, vobject):
+ vobject.vreg = self
+ vobject.schema = self.schema
+ vobject.config = self.config
+
+
from datetime import datetime, date, time, timedelta
YAMS_TO_PY = {
--- a/devtools/_apptest.py Thu Jul 02 10:30:44 2009 +0200
+++ b/devtools/_apptest.py Thu Jul 02 10:35:03 2009 +0200
@@ -177,7 +177,7 @@
self.create_request(rql=rql, **optional_args or {}))
def check_view(self, rql, vid, optional_args, template='main'):
- """checks if vreg.view() raises an exception in this environment
+ """checks if rendering view raises an exception in this environment
If any exception is raised in this method, it will be considered
as a TestFailure
@@ -186,7 +186,6 @@
template=template, optional_args=optional_args)
def call_view(self, vid, rql, template='main', optional_args=None):
- """shortcut for self.vreg.view()"""
assert template
if optional_args is None:
optional_args = {}
@@ -196,7 +195,7 @@
def call_edit(self, req):
"""shortcut for self.app.edit()"""
- controller = self.app.select_controller('edit', req)
+ controller = self.vreg.select('controllers', 'edit', req)
try:
controller.publish()
except Redirect:
@@ -224,7 +223,7 @@
def iter_possible_actions(self, req, rset):
"""returns a list of possible vids for <rql>"""
- for action in self.vreg.possible_vobjects('actions', req, rset):
+ for action in self.vreg.possible_vobjects('actions', req, rset=rset):
yield action
class ExistingTestEnvironment(TestEnvironment):
--- a/devtools/apptest.py Thu Jul 02 10:30:44 2009 +0200
+++ b/devtools/apptest.py Thu Jul 02 10:35:03 2009 +0200
@@ -219,18 +219,18 @@
return sorted((a.id, a.__class__) for a in self.vreg.possible_views(req, rset))
def pactions(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')):
- return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset)
+ return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset=rset)
if a.category not in skipcategories]
def pactions_by_cats(self, req, rset, categories=('addrelated',)):
- return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset)
+ return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset=rset)
if a.category in categories]
paddrelactions = deprecated_function(pactions_by_cats)
def pactionsdict(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')):
res = {}
- for a in self.vreg.possible_vobjects('actions', req, rset):
+ for a in self.vreg.possible_vobjects('actions', req, rset=rset):
if a.category not in skipcategories:
res.setdefault(a.category, []).append(a.__class__)
return res
@@ -241,7 +241,7 @@
dump = simplejson.dumps
args = [dump(arg) for arg in args]
req = self.request(fname=fname, pageid='123', arg=args)
- ctrl = self.env.app.select_controller('json', req)
+ ctrl = self.vreg.select('controllers', 'json', req)
return ctrl.publish(), req
# default test setup and teardown #########################################
@@ -286,7 +286,7 @@
def setUp(self):
super(ControllerTC, self).setUp()
self.req = self.request()
- self.ctrl = self.env.app.select_controller('edit', self.req)
+ self.ctrl = self.vreg.select('controllers', 'edit', self.req)
def publish(self, req):
assert req is self.ctrl.req
@@ -300,7 +300,7 @@
def expect_redirect_publish(self, req=None):
if req is not None:
- self.ctrl = self.env.app.select_controller('edit', req)
+ self.ctrl = self.vreg.select('controllers', 'edit', req)
else:
req = self.req
try:
--- a/devtools/fake.py Thu Jul 02 10:30:44 2009 +0200
+++ b/devtools/fake.py Thu Jul 02 10:35:03 2009 +0200
@@ -154,6 +154,25 @@
return self.execute(*args, **kwargs)
+# class FakeRequestNoCnx(FakeRequest):
+# def get_session_data(self, key, default=None, pop=False):
+# """return value associated to `key` in session data"""
+# if pop:
+# return self._session_data.pop(key, default)
+# else:
+# return self._session_data.get(key, default)
+
+# def set_session_data(self, key, value):
+# """set value associated to `key` in session data"""
+# self._session_data[key] = value
+
+# def del_session_data(self, key):
+# try:
+# del self._session_data[key]
+# except KeyError:
+# pass
+
+
class FakeUser(object):
login = 'toto'
eid = 0
--- a/devtools/testlib.py Thu Jul 02 10:30:44 2009 +0200
+++ b/devtools/testlib.py Thu Jul 02 10:35:03 2009 +0200
@@ -44,7 +44,7 @@
# compute how many entities by type we need to be able to satisfy relation constraint
relmap = {}
for rschema in schema.relations():
- if rschema.meta or rschema.is_final(): # skip meta relations
+ if rschema.is_final():
continue
for subj, obj in rschema.iter_rdefs():
card = rschema.rproperty(subj, obj, 'cardinality')
@@ -172,7 +172,8 @@
return validator.parse_string(output.strip())
- def view(self, vid, rset, req=None, template='main-template', **kwargs):
+ def view(self, vid, rset=None, req=None, template='main-template',
+ **kwargs):
"""This method tests the view `vid` on `rset` using `template`
If no error occured while rendering the view, the HTML is analyzed
@@ -183,7 +184,8 @@
"""
req = req or rset and rset.req or self.request()
req.form['vid'] = vid
- view = self.vreg.select_view(vid, req, rset, **kwargs)
+ kwargs['rset'] = rset
+ view = self.vreg.select('views', vid, req, **kwargs)
# set explicit test description
if rset is not None:
self.set_description("testing %s, mod=%s (%s)" % (
@@ -194,9 +196,11 @@
if template is None: # raw view testing, no template
viewfunc = view.render
else:
- templateview = self.vreg.select_view(template, req, rset, view=view, **kwargs)
kwargs['view'] = view
- viewfunc = lambda **k: self.vreg.main_template(req, template, **kwargs)
+ templateview = self.vreg.select('views', template, req, **kwargs)
+ viewfunc = lambda **k: self.vreg.main_template(req, template,
+ **kwargs)
+ kwargs.pop('rset')
return self._test_view(viewfunc, view, template, kwargs)
@@ -278,7 +282,7 @@
and not issubclass(view, NotificationView)]
if views:
try:
- view = self.vreg.select(views, req, rset)
+ view = self.vreg.select_best(views, req, rset=rset)
if view.linkable():
yield view
else:
@@ -291,13 +295,13 @@
def list_actions_for(self, rset):
"""returns the list of actions that can be applied on `rset`"""
req = rset.req
- for action in self.vreg.possible_objects('actions', req, rset):
+ for action in self.vreg.possible_objects('actions', req, rset=rset):
yield action
def list_boxes_for(self, rset):
"""returns the list of boxes that can be applied on `rset`"""
req = rset.req
- for box in self.vreg.possible_objects('boxes', req, rset):
+ for box in self.vreg.possible_objects('boxes', req, rset=rset):
yield box
def list_startup_views(self):
@@ -383,9 +387,9 @@
requestcls=testclass.requestcls)
vreg = env.vreg
vreg._selected = {}
- orig_select = vreg.__class__.select
- def instr_select(self, *args, **kwargs):
- selected = orig_select(self, *args, **kwargs)
+ orig_select_best = vreg.__class__.select_best
+ def instr_select_best(self, *args, **kwargs):
+ selected = orig_select_best(self, *args, **kwargs)
try:
self._selected[selected.__class__] += 1
except KeyError:
@@ -393,7 +397,7 @@
except AttributeError:
pass # occurs on vreg used to restore database
return selected
- vreg.__class__.select = instr_select
+ vreg.__class__.select_best = instr_select_best
def print_untested_objects(testclass, skipregs=('hooks', 'etypes')):
vreg = testclass._env.vreg
--- a/entities/__init__.py Thu Jul 02 10:30:44 2009 +0200
+++ b/entities/__init__.py Thu Jul 02 10:35:03 2009 +0200
@@ -242,12 +242,12 @@
@obsolete('use EntityFieldsForm.subject_relation_vocabulary')
def subject_relation_vocabulary(self, rtype, limit):
- form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
+ form = self.vreg.select('forms', 'edition', self.req, entity=self)
return form.subject_relation_vocabulary(rtype, limit)
@obsolete('use EntityFieldsForm.object_relation_vocabulary')
def object_relation_vocabulary(self, rtype, limit):
- form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
+ form = self.vreg.select('forms', 'edition', self.req, entity=self)
return form.object_relation_vocabulary(rtype, limit)
@obsolete('use AutomaticEntityForm.[e]relations_by_category')
--- a/entities/schemaobjs.py Thu Jul 02 10:30:44 2009 +0200
+++ b/entities/schemaobjs.py Thu Jul 02 10:35:03 2009 +0200
@@ -25,8 +25,6 @@
def dc_long_title(self):
stereotypes = []
_ = self.req._
- if self.meta:
- stereotypes.append(_('meta'))
if self.final:
stereotypes.append(_('final'))
if stereotypes:
--- a/entity.py Thu Jul 02 10:30:44 2009 +0200
+++ b/entity.py Thu Jul 02 10:35:03 2009 +0200
@@ -368,13 +368,20 @@
def has_perm(self, action):
return self.e_schema.has_perm(self.req, action, self.eid)
- def view(self, vid, __registry='views', **kwargs):
+ def view(self, vid, **kwargs):
"""shortcut to apply a view on this entity"""
- return self.vreg.render(__registry, vid, self.req, rset=self.rset,
+ return self.vreg.render(vid, self.req, rset=self.rset,
row=self.row, col=self.col, **kwargs)
- def absolute_url(self, method=None, **kwargs):
+ def absolute_url(self, *args, **kwargs):
"""return an absolute url to view this entity"""
+ # use *args since we don't want first argument to be "anonymous" to
+ # avoid potential clash with kwargs
+ if args:
+ assert len(args) == 1, 'only 0 or 1 non-named-argument expected'
+ method = args[0]
+ else:
+ method = None
# in linksearch mode, we don't want external urls else selecting
# the object for use in the relation is tricky
# XXX search_state is web specific
@@ -478,7 +485,7 @@
assert self.has_eid()
execute = self.req.execute
for rschema in self.e_schema.subject_relations():
- if rschema.meta or rschema.is_final():
+ if rschema.is_final() or rschema.meta:
continue
# skip already defined relations
if getattr(self, rschema.type):
@@ -725,7 +732,7 @@
interpreted as a separator in case vocabulary results are grouped
"""
from logilab.common.testlib import mock_object
- form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
+ form = self.vreg.select('forms', 'edition', self.req, entity=self)
field = mock_object(name=rtype, role=role)
return form.form_field_vocabulary(field, limit)
--- a/etwist/server.py Thu Jul 02 10:30:44 2009 +0200
+++ b/etwist/server.py Thu Jul 02 10:35:03 2009 +0200
@@ -106,10 +106,7 @@
self.pyro_listen_timeout = 0.02
start_task(1, self.pyro_loop_event)
self.appli.repo.start_looping_tasks()
- try:
- self.url_rewriter = self.appli.vreg.select_component('urlrewriter')
- except ObjectNotFound:
- self.url_rewriter = None
+ self.url_rewriter = self.appli.vreg.select_object('components', 'urlrewriter')
interval = min(config['cleanup-session-time'] or 120,
config['cleanup-anonymous-session-time'] or 720) / 2.
start_task(interval, self.appli.session_handler.clean_sessions)
--- a/goa/appobjects/components.py Thu Jul 02 10:30:44 2009 +0200
+++ b/goa/appobjects/components.py Thu Jul 02 10:35:03 2009 +0200
@@ -45,7 +45,7 @@
content_type = 'image/png'
def call(self):
"""display global schema information"""
- skipmeta = not int(self.req.form.get('withmeta', 0))
+ skipmeta = int(self.req.form.get('skipmeta', 1))
if skipmeta:
url = self.build_url('data/schema.png')
else:
@@ -72,7 +72,7 @@
continue
etype = eschema.type
label = display_name(req, etype, 'plural')
- view = self.vreg.select_view('list', req, req.etype_rset(etype))
+ view = self.vreg.select('views', 'list', req, req.etype_rset(etype))
url = view.url()
etypelink = u' <a href="%s">%s</a>' % (html_escape(url), label)
yield (label, etypelink, self.add_entity_link(eschema, req))
--- a/goa/dbinit.py Thu Jul 02 10:30:44 2009 +0200
+++ b/goa/dbinit.py Thu Jul 02 10:35:03 2009 +0200
@@ -86,14 +86,13 @@
def init_persistent_schema(ssession, schema):
execute = ssession.unsafe_execute
rql = ('INSERT CWEType X: X name %(name)s, X description %(descr)s,'
- 'X final FALSE, X meta %(meta)s')
+ 'X final FALSE')
eschema = schema.eschema('CWEType')
- execute(rql, {'name': u'CWEType', 'descr': unicode(eschema.description),
- 'meta': eschema.meta})
+ execute(rql, {'name': u'CWEType', 'descr': unicode(eschema.description)})
for eschema in schema.entities():
if eschema.is_final() or eschema == 'CWEType':
continue
- execute(rql, {'name': unicode(eschema), 'meta': eschema.meta,
+ execute(rql, {'name': unicode(eschema),
'descr': unicode(eschema.description)})
def insert_versions(ssession, config):
--- a/goa/test/unittest_editcontroller.py Thu Jul 02 10:30:44 2009 +0200
+++ b/goa/test/unittest_editcontroller.py Thu Jul 02 10:35:03 2009 +0200
@@ -37,8 +37,7 @@
self.ctrl = self.get_ctrl(self.req)
def get_ctrl(self, req):
- return self.vreg.select(self.vreg.registry_objects('controllers', 'edit'),
- req=req, appli=self)
+ return self.vreg.select('controllers', 'edit', req=req, appli=self)
def publish(self, req):
assert req is self.ctrl.req
--- a/goa/testlib.py Thu Jul 02 10:30:44 2009 +0200
+++ b/goa/testlib.py Thu Jul 02 10:35:03 2009 +0200
@@ -131,7 +131,7 @@
self.vreg.load_module(module)
for cls in self.MODEL_CLASSES:
self.vreg.load_object(cls)
- self.session_manager = self.vreg.select_component('sessionmanager')
+ self.session_manager = self.vreg.select('components', 'sessionmanager')
if need_ds_init:
# create default groups and create entities according to the schema
create_groups()
--- a/goa/tools/generate_schema_img.py Thu Jul 02 10:30:44 2009 +0200
+++ b/goa/tools/generate_schema_img.py Thu Jul 02 10:35:03 2009 +0200
@@ -8,6 +8,7 @@
import sys
from os.path import dirname, abspath, join
from yams import schema2dot
+from cubicweb.web.views.schema import SKIP_TYPES
APPLROOT = abspath(join(dirname(abspath(__file__)), '..'))
@@ -22,9 +23,8 @@
skip_rels = ('owned_by', 'created_by', 'identity', 'is', 'is_instance_of')
path = join(APPLROOT, 'data', 'schema.png')
schema2dot.schema2dot(schema, path, #size=size,
- skiprels=skip_rels, skipmeta=True)
+ skiptypes=SKIP_TYPES)
print 'generated', path
path = join(APPLROOT, 'data', 'metaschema.png')
-schema2dot.schema2dot(schema, path, #size=size,
- skiprels=skip_rels, skipmeta=False)
+schema2dot.schema2dot(schema, path)
print 'generated', path
--- a/goa/tools/laxctl.py Thu Jul 02 10:30:44 2009 +0200
+++ b/goa/tools/laxctl.py Thu Jul 02 10:35:03 2009 +0200
@@ -19,6 +19,8 @@
from logilab.common.clcommands import Command, register_commands, main_run
from cubicweb.common.uilib import remove_html_tags
+from cubicweb.web.views.schema import SKIP_TYPES
+
APPLROOT = osp.abspath(osp.join(osp.dirname(osp.abspath(__file__)), '..'))
@@ -57,14 +59,12 @@
assert not args, 'no argument expected'
from yams import schema2dot
schema = self.vreg.schema
- skip_rels = ('owned_by', 'created_by', 'identity', 'is', 'is_instance_of')
path = osp.join(APPLROOT, 'data', 'schema.png')
schema2dot.schema2dot(schema, path, #size=size,
- skiprels=skip_rels, skipmeta=True)
+ skiptypes=SKIP_TYPES)
print 'generated', path
path = osp.join(APPLROOT, 'data', 'metaschema.png')
- schema2dot.schema2dot(schema, path, #size=size,
- skiprels=skip_rels, skipmeta=False)
+ schema2dot.schema2dot(schema, path)
print 'generated', path
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.4.0_Any.py Thu Jul 02 10:35:03 2009 +0200
@@ -0,0 +1,2 @@
+drop_attribute('CWEType', 'meta')
+drop_attribute('CWRType', 'meta')
--- a/rset.py Thu Jul 02 10:30:44 2009 +0200
+++ b/rset.py Thu Jul 02 10:35:03 2009 +0200
@@ -83,7 +83,8 @@
try:
return self._rsetactions[key]
except KeyError:
- actions = self.vreg.possible_vobjects('actions', self.req, self, **kwargs)
+ actions = self.vreg.possible_vobjects('actions', self.req,
+ rset=self, **kwargs)
self._rsetactions[key] = actions
return actions
--- a/schema.py Thu Jul 02 10:30:44 2009 +0200
+++ b/schema.py Thu Jul 02 10:35:03 2009 +0200
@@ -20,8 +20,7 @@
from yams import BadSchemaDefinition, buildobjs as ybo
from yams.schema import Schema, ERSchema, EntitySchema, RelationSchema
from yams.constraints import BaseConstraint, StaticVocabularyConstraint
-from yams.reader import (CONSTRAINTS, RelationFileReader, PyFileReader,
- SchemaLoader)
+from yams.reader import CONSTRAINTS, PyFileReader, SchemaLoader
from rql import parse, nodes, RQLSyntaxError, TypeResolverException
@@ -33,7 +32,22 @@
schema.use_py_datetime()
nodes.use_py_datetime()
-BASEGROUPS = ('managers', 'users', 'guests', 'owners')
+# set of meta-relations available for every entity types
+META_RELATIONS_TYPES = set((
+ 'owned_by', 'created_by', 'is', 'is_instance_of', 'identity',
+ 'eid', 'creation_date', 'modification_date', 'has_text',
+ ))
+
+# set of entity and relation types used to build the schema
+SCHEMA_TYPES = set((
+ 'CWEType', 'CWRType', 'CWAttribute', 'CWRelation',
+ 'CWConstraint', 'CWConstraintType', 'RQLExpression',
+ 'relation_type', 'from_entity', 'to_entity',
+ 'constrained_by', 'cstrtype',
+ # XXX those are not really "schema" entity types
+ # but we usually don't want them as @* targets
+ 'CWProperty', 'CWPermission', 'State', 'Transition',
+ ))
_LOGGER = getLogger('cubicweb.schemaloader')
@@ -50,31 +64,6 @@
etype = ETYPE_NAME_MAP[etype]
return etype
-# monkey path yams.builder.RelationDefinition to support a new wildcard type '@'
-# corresponding to system entity (ie meta but not schema)
-def _actual_types(self, schema, etype):
- # two bits of error checking & reporting :
- if type(etype) not in (str, list, tuple):
- raise RuntimeError, ('Entity types must not be instances but strings or'
- ' list/tuples thereof. Ex. (bad, good) : '
- 'SubjectRelation(Foo), SubjectRelation("Foo"). '
- 'Hence, %r is not acceptable.' % etype)
- # real work :
- if etype == '**':
- return self._pow_etypes(schema)
- if isinstance(etype, (tuple, list)):
- return etype
- if '*' in etype or '@' in etype:
- assert len(etype) in (1, 2)
- etypes = ()
- if '*' in etype:
- etypes += tuple(self._wildcard_etypes(schema))
- if '@' in etype:
- etypes += tuple(system_etypes(schema))
- return etypes
- return (etype,)
-ybo.RelationDefinition._actual_types = _actual_types
-
## cubicweb provides a RichString class for convenience
class RichString(ybo.String):
@@ -253,7 +242,7 @@
"""return system entity types only: skip final, schema and application entities
"""
for eschema in schema.entities():
- if eschema.is_final() or eschema.schema_entity() or not eschema.meta:
+ if eschema.is_final() or eschema.schema_entity():
continue
yield eschema.type
@@ -293,6 +282,15 @@
continue
yield rschema, attrschema
+ def main_attribute(self):
+ """convenience method that returns the *main* (i.e. the first non meta)
+ attribute defined in the entity schema
+ """
+ for rschema, _ in self.attribute_definitions():
+ if not (rschema in META_RELATIONS_TYPES
+ or self.is_metadata(rschema)):
+ return rschema
+
def add_subject_relation(self, rschema):
"""register the relation schema as possible subject relation"""
super(CubicWebEntitySchema, self).add_subject_relation(rschema)
@@ -332,7 +330,7 @@
def schema_entity(self):
"""return True if this entity type is used to build the schema"""
- return self.type in self.schema.schema_entity_types()
+ return self.type in SCHEMA_TYPES
def check_perm(self, session, action, eid=None):
# NB: session may be a server session or a request object
@@ -369,6 +367,9 @@
eid = getattr(rdef, 'eid', None)
self.eid = eid
+ @property
+ def meta(self):
+ return self.type in META_RELATIONS_TYPES
def update(self, subjschema, objschema, rdef):
super(CubicWebRelationSchema, self).update(subjschema, objschema, rdef)
@@ -407,8 +408,8 @@
(target == 'object' and card[1])
def schema_relation(self):
- return self.type in ('relation_type', 'from_entity', 'to_entity',
- 'constrained_by', 'cstrtype')
+ """return True if this relation type is used to build the schema"""
+ return self.type in SCHEMA_TYPES
def physical_mode(self):
"""return an appropriate mode for physical storage of this relation type:
@@ -468,14 +469,6 @@
rschema.final = False
rschema.set_default_groups()
- def schema_entity_types(self):
- """return the list of entity types used to build the schema"""
- return frozenset(('CWEType', 'CWRType', 'CWAttribute', 'CWRelation',
- 'CWConstraint', 'CWConstraintType', 'RQLExpression',
- # XXX those are not really "schema" entity types
- # but we usually don't want them as @* targets
- 'CWProperty', 'CWPermission', 'State', 'Transition'))
-
def add_entity_type(self, edef):
edef.name = edef.name.encode()
edef.name = bw_normalize_etype(edef.name)
@@ -874,23 +867,6 @@
# schema loading ##############################################################
-class CubicWebRelationFileReader(RelationFileReader):
- """cubicweb specific relation file reader, handling additional RQL
- constraints on a relation definition
- """
-
- def handle_constraint(self, rdef, constraint_text):
- """arbitrary constraint is an rql expression for cubicweb"""
- if not rdef.constraints:
- rdef.constraints = []
- rdef.constraints.append(RQLVocabularyConstraint(constraint_text))
-
- def process_properties(self, rdef, relation_def):
- if 'inline' in relation_def:
- rdef.inlined = True
- RelationFileReader.process_properties(self, rdef, relation_def)
-
-
CONSTRAINTS['RQLConstraint'] = RQLConstraint
CONSTRAINTS['RQLUniqueConstraint'] = RQLUniqueConstraint
CONSTRAINTS['RQLVocabularyConstraint'] = RQLVocabularyConstraint
@@ -902,8 +878,6 @@
the persistent schema
"""
schemacls = CubicWebSchema
- SchemaLoader.file_handlers.update({'.rel' : CubicWebRelationFileReader,
- })
def load(self, config, path=(), **kwargs):
"""return a Schema instance from the schema definition read
--- a/schemas/Bookmark.py Thu Jul 02 10:30:44 2009 +0200
+++ b/schemas/Bookmark.py Thu Jul 02 10:35:03 2009 +0200
@@ -5,9 +5,20 @@
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
+__docformat__ = "restructuredtext en"
+_ = unicode
-class Bookmark(MetaUserEntityType):
+from yams.buildobjs import EntityType, RelationType, String
+
+class Bookmark(EntityType):
"""bookmarks are used to have user's specific internal links"""
+ permissions = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers', 'users',),
+ 'delete': ('managers', 'owners',),
+ 'update': ('managers', 'owners',),
+ }
+
title = String(required=True, maxsize=128, internationalizable=True)
path = String(maxsize=512, required=True,
description=_("relative url of the bookmarked page"))
@@ -16,7 +27,7 @@
description=_("users using this bookmark"))
-class bookmarked_by(MetaUserRelationType):
+class bookmarked_by(RelationType):
permissions = {'read': ('managers', 'users', 'guests',),
# test user in users group to avoid granting permission to anonymous user
'add': ('managers', RRQLExpression('O identity U, U in_group G, G name "users"')),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/schemas/__init__.py Thu Jul 02 10:35:03 2009 +0200
@@ -0,0 +1,13 @@
+
+META_ETYPE_PERMS = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers',),
+ 'delete': ('managers',),
+ 'update': ('managers', 'owners',),
+ }
+
+META_RTYPE_PERMS = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers',),
+ 'delete': ('managers',),
+ }
--- a/schemas/base.py Thu Jul 02 10:30:44 2009 +0200
+++ b/schemas/base.py Thu Jul 02 10:35:03 2009 +0200
@@ -6,11 +6,15 @@
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
+_ = unicode
+from yams.buildobjs import (EntityType, RelationType, SubjectRelation,
+ String, Boolean, Datetime)
+from cubicweb.schema import RQLConstraint
+from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS
class CWUser(WorkflowableEntityType):
"""define a CubicWeb user"""
- meta = True # XXX backported from old times, shouldn't be there anymore
permissions = {
'read': ('managers', 'users', ERQLExpression('X identity U')),
'add': ('managers',),
@@ -35,7 +39,7 @@
description=_('groups grant permissions to the user'))
-class EmailAddress(MetaEntityType):
+class EmailAddress(EntityType):
"""an electronic mail address associated to a short alias"""
permissions = {
'read': ('managers', 'users', 'guests',), # XXX if P use_email X, U has_read_permission P
@@ -81,11 +85,11 @@
'delete': ('managers', RRQLExpression('U has_update_permission S'),),
}
-class in_group(MetaRelationType):
+class in_group(RelationType):
"""core relation indicating a user's groups"""
- meta = False
+ permissions = META_RTYPE_PERMS
-class owned_by(MetaRelationType):
+class owned_by(RelationType):
"""core relation indicating owners of an entity. This relation
implicitly put the owner into the owners group for the entity
"""
@@ -100,7 +104,7 @@
subject = '**'
object = 'CWUser'
-class created_by(MetaRelationType):
+class created_by(RelationType):
"""core relation indicating the original creator of an entity"""
permissions = {
'read': ('managers', 'users', 'guests'),
@@ -114,13 +118,13 @@
object = 'CWUser'
-class creation_date(MetaAttributeRelationType):
+class creation_date(RelationType):
"""creation time of an entity"""
cardinality = '11'
subject = '**'
object = 'Datetime'
-class modification_date(MetaAttributeRelationType):
+class modification_date(RelationType):
"""latest modification time of an entity"""
cardinality = '11'
subject = '**'
@@ -137,7 +141,6 @@
'update': ('managers', 'owners',),
'delete': ('managers', 'owners',),
}
- meta = True
# key is a reserved word for mysql
pkey = String(required=True, internationalizable=True, maxsize=256,
description=_('defines what\'s the property is applied for. '
@@ -152,7 +155,7 @@
' a global property'))
-class for_user(MetaRelationType):
+class for_user(RelationType):
"""link a property to the user which want this property customization. Unless
you're a site manager, this relation will be handled automatically.
"""
@@ -164,9 +167,11 @@
inlined = True
-class CWPermission(MetaEntityType):
+class CWPermission(EntityType):
"""entity type that may be used to construct some advanced security configuration
"""
+ permissions = META_ETYPE_PERMS
+
name = String(required=True, indexed=True, internationalizable=True, maxsize=100,
description=_('name or identifier of the permission'))
label = String(required=True, internationalizable=True, maxsize=100,
@@ -186,7 +191,7 @@
'delete': ('managers',),
}
-class require_group(MetaRelationType):
+class require_group(RelationType):
"""used to grant a permission to a group"""
permissions = {
'read': ('managers', 'users', 'guests'),
@@ -200,7 +205,7 @@
symetric = True
-class CWCache(MetaEntityType):
+class CWCache(EntityType):
"""a simple cache entity characterized by a name and
a validity date.
@@ -212,7 +217,7 @@
permissions = {
'read': ('managers', 'users', 'guests'),
'add': ('managers',),
- 'update': ('managers', 'users',),
+ 'update': ('managers', 'users',), # XXX
'delete': ('managers',),
}
--- a/schemas/bootstrap.py Thu Jul 02 10:30:44 2009 +0200
+++ b/schemas/bootstrap.py Thu Jul 02 10:35:03 2009 +0200
@@ -5,32 +5,34 @@
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
+__docformat__ = "restructuredtext en"
+_ = unicode
-from cubicweb.schema import format_constraint
-
+from yams.buildobjs import (EntityType, RelationType, SubjectRelation,
+ ObjectRelation, String, Boolean, Int)
+from cubicweb.schema import RichString, RQLConstraint
+from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS
# not restricted since as "is" is handled as other relations, guests need
# access to this
-class CWEType(MetaEntityType):
+class CWEType(EntityType):
"""define an entity type, used to build the application schema"""
+ permissions = META_ETYPE_PERMS
name = String(required=True, indexed=True, internationalizable=True,
unique=True, maxsize=64)
description = RichString(internationalizable=True,
description=_('semantic description of this entity type'))
- meta = Boolean(description=_('is it an application entity type or not ?'))
# necessary to filter using RQL
final = Boolean(description=_('automatic'))
-class CWRType(MetaEntityType):
+class CWRType(EntityType):
"""define a relation type, used to build the application schema"""
+ permissions = META_ETYPE_PERMS
name = String(required=True, indexed=True, internationalizable=True,
unique=True, maxsize=64)
- description_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/plain', constraints=[format_constraint])
- description = String(internationalizable=True,
- description=_('semantic description of this relation type'))
- meta = Boolean(description=_('is it an application relation type or not ?'))
+ description = RichString(internationalizable=True,
+ description=_('semantic description of this relation type'))
symetric = Boolean(description=_('is this relation equivalent in both direction ?'))
inlined = Boolean(description=_('is this relation physically inlined? you should know what you\'re doing if you are changing this!'))
fulltext_container = String(description=_('if full text content of subject/object entity '
@@ -40,12 +42,13 @@
final = Boolean(description=_('automatic'))
-class CWAttribute(MetaEntityType):
+class CWAttribute(EntityType):
"""define a final relation: link a final relation type from a non final
entity to a final entity type.
used to build the application schema
"""
+ permissions = META_ETYPE_PERMS
relation_type = SubjectRelation('CWRType', cardinality='1*',
constraints=[RQLConstraint('O final TRUE')],
composite='object')
@@ -67,10 +70,8 @@
internationalizable = Boolean(description=_('is this attribute\'s value translatable'))
defaultval = String(maxsize=256)
- description_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/plain', constraints=[format_constraint])
- description = String(internationalizable=True,
- description=_('semantic description of this attribute'))
+ description = RichString(internationalizable=True,
+ description=_('semantic description of this attribute'))
CARDINALITY_VOCAB = [_('?*'), _('1*'), _('+*'), _('**'),
@@ -78,12 +79,13 @@
_('?1'), _('11'), _('+1'), _('*1'),
_('??'), _('1?'), _('+?'), _('*?')]
-class CWRelation(MetaEntityType):
+class CWRelation(EntityType):
"""define a non final relation: link a non final relation type from a non
final entity to a non final entity type.
used to build the application schema
"""
+ permissions = META_ETYPE_PERMS
relation_type = SubjectRelation('CWRType', cardinality='1*',
constraints=[RQLConstraint('O final FALSE')],
composite='object')
@@ -107,15 +109,14 @@
vocabulary=('', _('subject'), _('object')),
maxsize=8, default=None)
- description_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/plain', constraints=[format_constraint])
- description = String(internationalizable=True,
- description=_('semantic description of this relation'))
+ description = RichString(internationalizable=True,
+ description=_('semantic description of this relation'))
# not restricted since it has to be read when checking allowed transitions
-class RQLExpression(MetaEntityType):
+class RQLExpression(EntityType):
"""define a rql expression used to define permissions"""
+ permissions = META_ETYPE_PERMS
exprtype = String(required=True, vocabulary=['ERQLExpression', 'RRQLExpression'])
mainvars = String(maxsize=8,
description=_('name of the main variables which should be '
@@ -140,21 +141,24 @@
description=_('rql expression allowing to update entities of this type'))
-class CWConstraint(MetaEntityType):
+class CWConstraint(EntityType):
"""define a schema constraint"""
+ permissions = META_ETYPE_PERMS
cstrtype = SubjectRelation('CWConstraintType', cardinality='1*')
value = String(description=_('depends on the constraint type'))
-class CWConstraintType(MetaEntityType):
+class CWConstraintType(EntityType):
"""define a schema constraint type"""
+ permissions = META_ETYPE_PERMS
name = String(required=True, indexed=True, internationalizable=True,
unique=True, maxsize=64)
# not restricted since it has to be read when checking allowed transitions
-class CWGroup(MetaEntityType):
+class CWGroup(EntityType):
"""define a CubicWeb users group"""
+ permissions = META_ETYPE_PERMS
name = String(required=True, indexed=True, internationalizable=True,
unique=True, maxsize=64)
@@ -169,40 +173,55 @@
-class relation_type(MetaRelationType):
+class relation_type(RelationType):
"""link a relation definition to its relation type"""
- inlined = True
-class from_entity(MetaRelationType):
- """link a relation definition to its subject entity type"""
+ permissions = META_RTYPE_PERMS
inlined = True
-class to_entity(MetaRelationType):
- """link a relation definition to its object entity type"""
- inlined = True
-class constrained_by(MetaRelationType):
- """constraints applying on this relation"""
-class cstrtype(MetaRelationType):
- """constraint factory"""
+class from_entity(RelationType):
+ """link a relation definition to its subject entity type"""
+ permissions = META_RTYPE_PERMS
inlined = True
-class read_permission(MetaRelationType):
+class to_entity(RelationType):
+ """link a relation definition to its object entity type"""
+ permissions = META_RTYPE_PERMS
+ inlined = True
+
+class constrained_by(RelationType):
+ """constraints applying on this relation"""
+ permissions = META_RTYPE_PERMS
+
+class cstrtype(RelationType):
+ """constraint factory"""
+ permissions = META_RTYPE_PERMS
+ inlined = True
+
+class read_permission(RelationType):
"""core relation giving to a group the permission to read an entity or
relation type
"""
-class add_permission(MetaRelationType):
+ permissions = META_RTYPE_PERMS
+
+class add_permission(RelationType):
"""core relation giving to a group the permission to add an entity or
relation type
"""
-class delete_permission(MetaRelationType):
+ permissions = META_RTYPE_PERMS
+
+class delete_permission(RelationType):
"""core relation giving to a group the permission to delete an entity or
relation type
"""
-class update_permission(MetaRelationType):
+ permissions = META_RTYPE_PERMS
+
+class update_permission(RelationType):
"""core relation giving to a group the permission to update an entity type
"""
+ permissions = META_RTYPE_PERMS
-class is_(MetaRelationType):
+class is_(RelationType):
"""core relation indicating the type of an entity
"""
name = 'is'
@@ -217,7 +236,7 @@
subject = '**'
object = 'CWEType'
-class is_instance_of(MetaRelationType):
+class is_instance_of(RelationType):
"""core relation indicating the types (including specialized types)
of an entity
"""
@@ -232,7 +251,7 @@
subject = '**'
object = 'CWEType'
-class specializes(MetaRelationType):
+class specializes(RelationType):
name = 'specializes'
permissions = {
'read': ('managers', 'users', 'guests'),
--- a/schemas/workflow.py Thu Jul 02 10:30:44 2009 +0200
+++ b/schemas/workflow.py Thu Jul 02 10:35:03 2009 +0200
@@ -5,11 +5,20 @@
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
+__docformat__ = "restructuredtext en"
+_ = unicode
-class State(MetaEntityType):
+from yams.buildobjs import (EntityType, RelationType, SubjectRelation,
+ ObjectRelation, String)
+from cubicweb.schema import RichString, RQLConstraint
+from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS
+
+class State(EntityType):
"""used to associate simple states to an entity type and/or to define
workflows
"""
+ permissions = META_ETYPE_PERMS
+
name = String(required=True, indexed=True, internationalizable=True,
maxsize=256)
description = RichString(fulltextindexed=True, default_format='text/rest',
@@ -28,15 +37,15 @@
description=_('initial state for entities of this type'))
-class Transition(MetaEntityType):
+class Transition(EntityType):
"""use to define a transition from one or multiple states to a destination
states in workflow's definitions.
"""
+ permissions = META_ETYPE_PERMS
+
name = String(required=True, indexed=True, internationalizable=True,
maxsize=256)
- description_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/rest', constraints=[format_constraint])
- description = String(fulltextindexed=True,
+ description = RichString(fulltextindexed=True,
description=_('semantic description of this transition'))
condition = SubjectRelation('RQLExpression', cardinality='*?', composite='subject',
description=_('a RQL expression which should return some results, '
@@ -56,20 +65,22 @@
description=_('destination state for this transition'))
-class TrInfo(MetaEntityType):
+class TrInfo(EntityType):
+ permissions = META_ETYPE_PERMS
+
from_state = SubjectRelation('State', cardinality='?*')
to_state = SubjectRelation('State', cardinality='1*')
- comment_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/rest', constraints=[format_constraint])
- comment = String(fulltextindexed=True)
+ comment = RichString(fulltextindexed=True)
# get actor and date time using owned_by and creation_date
-class from_state(MetaRelationType):
+class from_state(RelationType):
+ permissions = META_RTYPE_PERMS
inlined = True
-class to_state(MetaRelationType):
+class to_state(RelationType):
+ permissions = META_RTYPE_PERMS
inlined = True
-class wf_info_for(MetaRelationType):
+class wf_info_for(RelationType):
"""link a transition information to its object"""
permissions = {
'read': ('managers', 'users', 'guests',),# RRQLExpression('U has_read_permission O')),
@@ -80,30 +91,39 @@
composite = 'object'
fulltext_container = composite
-class state_of(MetaRelationType):
+class state_of(RelationType):
"""link a state to one or more entity type"""
-class transition_of(MetaRelationType):
+ permissions = META_RTYPE_PERMS
+class transition_of(RelationType):
"""link a transition to one or more entity type"""
+ permissions = META_RTYPE_PERMS
-class initial_state(MetaRelationType):
+class initial_state(RelationType):
"""indicate which state should be used by default when an entity using
states is created
"""
- inlined = True
-
-class destination_state(MetaRelationType):
- """destination state of a transition"""
+ permissions = META_RTYPE_PERMS
inlined = True
-class allowed_transition(MetaRelationType):
- """allowed transition from this state"""
+class destination_state(RelationType):
+ """destination state of a transition"""
+ permissions = META_RTYPE_PERMS
+ inlined = True
-class in_state(UserRelationType):
+class allowed_transition(RelationType):
+ """allowed transition from this state"""
+ permissions = META_RTYPE_PERMS
+
+class in_state(RelationType):
"""indicate the current state of an entity"""
- meta = True
# not inlined intentionnaly since when using ldap sources, user'state
# has to be stored outside the CWUser table
# add/delete perms given to managers/users, after what most of the job
# is done by workflow enforcment
+ permissions = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers', 'users',), # XXX has_update_perm
+ 'delete': ('managers', 'users',),
+ }
--- a/schemaviewer.py Thu Jul 02 10:30:44 2009 +0200
+++ b/schemaviewer.py Thu Jul 02 10:35:03 2009 +0200
@@ -6,11 +6,11 @@
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
+_ = unicode
from logilab.common.ureports import Section, Title, Table, Link, Span, Text
from yams.schema2dot import CARD_MAP
-_ = unicode
I18NSTRINGS = [_('read'), _('add'), _('delete'), _('update'), _('order')]
class SchemaViewer(object):
@@ -38,8 +38,7 @@
klass='acl')
- def visit_schema(self, schema, display_relations=0,
- skiprels=(), skipmeta=True):
+ def visit_schema(self, schema, display_relations=0, skiptypes=()):
"""get a layout for a whole schema"""
title = Title(self.req._('Schema %s') % schema.name,
klass='titleUnderline')
@@ -48,21 +47,15 @@
klass='titleUnderline'),))
layout.append(esection)
eschemas = [eschema for eschema in schema.entities()
- if not eschema.is_final()]
- if skipmeta:
- eschemas = [eschema for eschema in eschemas
- if not eschema.meta]
+ if not (eschema.is_final() or eschema in skiptypes)]
for eschema in sorted(eschemas):
- esection.append(self.visit_entityschema(eschema, skiprels))
+ esection.append(self.visit_entityschema(eschema, skiptypes))
if display_relations:
title = Title(self.req._('Relations'), klass='titleUnderline')
rsection = Section(children=(title,))
layout.append(rsection)
relations = [rschema for rschema in schema.relations()
- if not (rschema.is_final() or rschema.type in skiprels)]
- if skipmeta:
- relations = [rschema for rschema in relations
- if not rschema.meta]
+ if not (rschema.is_final() or rschema.type in skiptypes)]
keys = [(rschema.type, rschema) for rschema in relations]
for key, rschema in sorted(keys):
relstr = self.visit_relationschema(rschema)
@@ -107,17 +100,13 @@
def stereotype(self, name):
return Span((' <<%s>>' % name,), klass='stereotype')
- def visit_entityschema(self, eschema, skiprels=()):
+ def visit_entityschema(self, eschema, skiptypes=()):
"""get a layout for an entity schema"""
etype = eschema.type
layout = Section(children=' ', klass='clear')
layout.append(Link(etype,' ' , id=etype)) # anchor
title = Link(self.eschema_link_url(eschema), etype)
- if eschema.meta:
- stereotype = self.stereotype('meta')
- boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req), stereotype), klass='title')]
- else:
- boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req)), klass='title')]
+ boxchild = [Section(children=(title, ' (%s)'% eschema.display_name(self.req)), klass='title')]
table = Table(cols=4, rheaders=1,
children=self._entity_attributes_data(eschema))
boxchild.append(Section(children=(table,), klass='body'))
@@ -129,7 +118,7 @@
rels = []
first = True
for rschema, targetschemas, x in eschema.relation_definitions():
- if rschema.type in skiprels:
+ if rschema.type in skiptypes:
continue
if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
continue
--- a/selectors.py Thu Jul 02 10:30:44 2009 +0200
+++ b/selectors.py Thu Jul 02 10:35:03 2009 +0200
@@ -287,7 +287,7 @@
@objectify_selector
@lltrace
-def none_rset(cls, req, rset=None, *args, **kwargs):
+def none_rset(cls, req, rset=None, **kwargs):
"""accept no result set (e.g. given rset is None)"""
if rset is None:
return 1
@@ -295,7 +295,7 @@
@objectify_selector
@lltrace
-def any_rset(cls, req, rset=None, *args, **kwargs):
+def any_rset(cls, req, rset=None, **kwargs):
"""accept result set, whatever the number of result it contains"""
if rset is not None:
return 1
@@ -303,7 +303,7 @@
@objectify_selector
@lltrace
-def nonempty_rset(cls, req, rset=None, *args, **kwargs):
+def nonempty_rset(cls, req, rset=None, **kwargs):
"""accept any non empty result set"""
if rset is not None and rset.rowcount:
return 1
@@ -311,7 +311,7 @@
@objectify_selector
@lltrace
-def empty_rset(cls, req, rset=None, *args, **kwargs):
+def empty_rset(cls, req, rset=None, **kwargs):
"""accept empty result set"""
if rset is not None and rset.rowcount == 0:
return 1
@@ -319,7 +319,7 @@
@objectify_selector
@lltrace
-def one_line_rset(cls, req, rset=None, row=None, *args, **kwargs):
+def one_line_rset(cls, req, rset=None, row=None, **kwargs):
"""if row is specified, accept result set with a single line of result,
else accepts anyway
"""
@@ -329,7 +329,7 @@
@objectify_selector
@lltrace
-def two_lines_rset(cls, req, rset=None, *args, **kwargs):
+def two_lines_rset(cls, req, rset=None, **kwargs):
"""accept result set with *at least* two lines of result"""
if rset is not None and rset.rowcount > 1:
return 1
@@ -337,7 +337,7 @@
@objectify_selector
@lltrace
-def two_cols_rset(cls, req, rset=None, *args, **kwargs):
+def two_cols_rset(cls, req, rset=None, **kwargs):
"""accept result set with at least one line and two columns of result"""
if rset is not None and rset.rowcount and len(rset.rows[0]) > 1:
return 1
@@ -345,7 +345,7 @@
@objectify_selector
@lltrace
-def paginated_rset(cls, req, rset=None, *args, **kwargs):
+def paginated_rset(cls, req, rset=None, **kwargs):
"""accept result set with more lines than the page size.
Page size is searched in (respecting order):
@@ -366,7 +366,7 @@
@objectify_selector
@lltrace
-def sorted_rset(cls, req, rset=None, row=None, col=0, **kwargs):
+def sorted_rset(cls, req, rset=None, **kwargs):
"""accept sorted result set"""
rqlst = rset.syntax_tree()
if len(rqlst.children) > 1 or not rqlst.children[0].orderby:
@@ -375,7 +375,7 @@
@objectify_selector
@lltrace
-def one_etype_rset(cls, req, rset=None, row=None, col=0, *args, **kwargs):
+def one_etype_rset(cls, req, rset=None, col=0, **kwargs):
"""accept result set where entities in the specified column (or 0) are all
of the same type
"""
@@ -387,7 +387,7 @@
@objectify_selector
@lltrace
-def two_etypes_rset(cls, req, rset=None, row=None, col=0, **kwargs):
+def two_etypes_rset(cls, req, rset=None, col=0, **kwargs):
"""accept result set where entities in the specified column (or 0) are not
of the same type
"""
@@ -573,7 +573,7 @@
def __call__(self, cls, req, rset=None, *args, **kwargs):
try:
- cls.vreg.select_object(self.registry, self.oid, req, rset, *args, **kwargs)
+ cls.vreg.select(self.registry, self.oid, req, rset=rset, **kwargs)
return 1
except NoSelectableObject:
return 0
@@ -935,6 +935,7 @@
def __repr__(self):
return u'<rql_condition "%s" at %x>' % (self.rql, id(self))
+
class but_etype(EntitySelector):
"""accept if the given entity types are not found in the result set.
--- a/server/__init__.py Thu Jul 02 10:30:44 2009 +0200
+++ b/server/__init__.py Thu Jul 02 10:35:03 2009 +0200
@@ -24,7 +24,7 @@
a initial user)
"""
from glob import glob
- from cubicweb.schema import BASEGROUPS
+ from yams import BASE_GROUPS
from cubicweb.dbapi import in_memory_cnx
from cubicweb.server.repository import Repository
from cubicweb.server.utils import manager_userpasswd
@@ -93,7 +93,7 @@
login, pwd = unicode(source['db-user']), source['db-password']
print 'inserting default user and groups'
needisfix = []
- for group in BASEGROUPS:
+ for group in BASE_GROUPS:
rset = session.execute('INSERT CWGroup X: X name %(name)s',
{'name': unicode(group)})
needisfix.append( (rset.rows[0][0], rset.description[0][0]) )
--- a/server/schemaserial.py Thu Jul 02 10:30:44 2009 +0200
+++ b/server/schemaserial.py Thu Jul 02 10:35:03 2009 +0200
@@ -114,10 +114,10 @@
index = {}
permsdict = deserialize_ertype_permissions(session)
schema.reading_from_database = True
- for eid, etype, desc, meta in session.execute('Any X, N, D, M WHERE '
- 'X is CWEType, X name N, '
- 'X description D, X meta M',
- build_descr=False):
+ for eid, etype, desc in session.execute('Any X, N, D WHERE '
+ 'X is CWEType, X name N, '
+ 'X description D',
+ build_descr=False):
# base types are already in the schema, skip them
if etype in schemamod.BASE_TYPES:
# just set the eid
@@ -152,7 +152,7 @@
repo.clear_caches(tocleanup)
session.commit(False)
etype = netype
- etype = ybo.EntityType(name=etype, description=desc, meta=meta, eid=eid)
+ etype = ybo.EntityType(name=etype, description=desc, eid=eid)
eschema = schema.add_entity_type(etype)
index[eid] = eschema
set_perms(eschema, permsdict.get(eid, {}))
@@ -167,9 +167,9 @@
seschema = schema.eschema(stype)
eschema._specialized_type = stype
seschema._specialized_by.append(etype)
- for eid, rtype, desc, meta, sym, il in session.execute(
- 'Any X,N,D,M,S,I WHERE X is CWRType, X name N, X description D, '
- 'X meta M, X symetric S, X inlined I', build_descr=False):
+ for eid, rtype, desc, sym, il in session.execute(
+ 'Any X,N,D,S,I WHERE X is CWRType, X name N, X description D, '
+ 'X symetric S, X inlined I', build_descr=False):
try:
# bw compat: fulltext_container added in 2.47
ft_container = session.execute('Any FTC WHERE X eid %(x)s, X fulltext_container FTC',
@@ -177,7 +177,7 @@
except:
ft_container = None
session.rollback(False)
- rtype = ybo.RelationType(name=rtype, description=desc, meta=bool(meta),
+ rtype = ybo.RelationType(name=rtype, description=desc,
symetric=bool(sym), inlined=bool(il),
fulltext_container=ft_container, eid=eid)
rschema = schema.add_relation_type(rtype)
@@ -326,7 +326,6 @@
raise Exception("can't decode %s [was %s]" % (erschema.description, e))
return {
'name': type_,
- 'meta': erschema.meta,
'final': erschema.is_final(),
'description': desc,
}
--- a/sobjects/notification.py Thu Jul 02 10:30:44 2009 +0200
+++ b/sobjects/notification.py Thu Jul 02 10:35:03 2009 +0200
@@ -14,7 +14,7 @@
try:
from socket import gethostname
except ImportError:
- def gethostname():
+ def gethostname(): # gae
return 'XXX'
from logilab.common.textutils import normalize_text
@@ -76,7 +76,7 @@
return
rset = entity.related('wf_info_for')
try:
- view = session.vreg.select_view('notif_status_change',
+ view = session.vreg.select('views', 'notif_status_change',
session, rset, row=0)
except RegistryException:
return
@@ -100,7 +100,7 @@
rset = session.eid_rset(fromeid)
vid = 'notif_%s_%s' % (self.event, rtype)
try:
- view = session.vreg.select_view(vid, session, rset, row=0)
+ view = session.vreg.select('views', vid, session, rset, row=0)
except RegistryException:
return
RenderAndSendNotificationView(session, view=view)
@@ -117,7 +117,7 @@
rset = entity.as_rset()
vid = 'notif_%s' % self.event
try:
- view = session.vreg.select_view(vid, session, rset, row=0)
+ view = session.vreg.select('views', vid, session, rset, row=0)
except RegistryException:
return
RenderAndSendNotificationView(session, view=view)
@@ -136,7 +136,8 @@
msgid_timestamp = True
def recipients(self):
- finder = self.vreg.select_component('recipients_finder', self.req, self.rset)
+ finder = self.vreg.select('components', 'recipients_finder', self.req,
+ rset=self.rset)
return finder.recipients()
def subject(self):
--- a/sobjects/supervising.py Thu Jul 02 10:30:44 2009 +0200
+++ b/sobjects/supervising.py Thu Jul 02 10:35:03 2009 +0200
@@ -217,8 +217,8 @@
of changes
"""
def _get_view(self):
- return self.session.vreg.select_component('supervision_notif',
- self.session, None)
+ return self.session.vreg.select('components', 'supervision_notif',
+ self.session)
def _prepare_email(self):
session = self.session
--- a/sobjects/test/unittest_notification.py Thu Jul 02 10:30:44 2009 +0200
+++ b/sobjects/test/unittest_notification.py Thu Jul 02 10:35:03 2009 +0200
@@ -56,7 +56,8 @@
self.execute('INSERT CWProperty X: X pkey "ui.language", X value "fr", X for_user U '
'WHERE U eid %(x)s', {'x': urset[0][0]})
self.commit() # commit so that admin get its properties updated
- finder = self.vreg.select_component('recipients_finder', self.request(), urset)
+ finder = self.vreg.select('components', 'recipients_finder', self.request(),
+ rset=urset)
self.set_option('default-recipients-mode', 'none')
self.assertEquals(finder.recipients(), [])
self.set_option('default-recipients-mode', 'users')
@@ -73,7 +74,7 @@
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)
+ v = self.vreg.select('views', 'notif_status_change', req, u.rset, row=0)
content = v.render(row=0, comment='yeah',
previous_state='activated',
current_state='deactivated')
--- a/vregistry.py Thu Jul 02 10:30:44 2009 +0200
+++ b/vregistry.py Thu Jul 02 10:35:03 2009 +0200
@@ -22,10 +22,11 @@
__docformat__ = "restructuredtext en"
import sys
+import types
from os import listdir, stat
from os.path import dirname, join, realpath, split, isdir, exists
from logging import getLogger
-import types
+from warnings import warn
from cubicweb import CW_SOFTWARE_ROOT, set_log_methods
from cubicweb import RegistryNotFound, ObjectNotFound, NoSelectableObject
@@ -169,28 +170,94 @@
If no oid is given, return all objects in this registry
"""
registry = self.registry(name)
- if oid:
+ if oid is not None:
try:
return registry[oid]
except KeyError:
raise ObjectNotFound(oid), None, sys.exc_info()[-1]
- else:
- result = []
- for objs in registry.values():
- result += objs
- return result
+ result = []
+ for objs in registry.values():
+ result += objs
+ return result
+
+ # dynamic selection methods ################################################
- def object_by_id(self, registry, cid, *args, **kwargs):
- """return the most specific component according to the resultset"""
- objects = self[registry][cid]
+ def object_by_id(self, registry, oid, *args, **kwargs):
+ """return object in <registry>.<oid>
+
+ raise `ObjectNotFound` if not object with id <oid> in <registry>
+ raise `AssertionError` if there is more than one object there
+ """
+ objects = self.registry_objects(registry, oid)
assert len(objects) == 1, objects
return objects[0].selected(*args, **kwargs)
+ def select(self, registry, oid, *args, **kwargs):
+ """return the most specific object in <registry>.<oid> according to
+ the given context
+
+ raise `ObjectNotFound` if not object with id <oid> in <registry>
+ raise `NoSelectableObject` if not object apply
+ """
+ return self.select_best(self.registry_objects(registry, oid),
+ *args, **kwargs)
+
+ def select_object(self, registry, oid, *args, **kwargs):
+ """return the most specific object in <registry>.<oid> according to
+ the given context, or None if no object apply
+ """
+ try:
+ return self.select(registry, oid, *args, **kwargs)
+ except (NoSelectableObject, ObjectNotFound):
+ return None
+
+ def possible_objects(self, registry, *args, **kwargs):
+ """return an iterator on possible objects in <registry> for the given
+ context
+ """
+ for vobjects in self.registry(registry).itervalues():
+ try:
+ yield self.select_best(vobjects, *args, **kwargs)
+ except NoSelectableObject:
+ continue
+
+ def select_best(self, vobjects, *args, **kwargs):
+ """return an instance of the most specific object according
+ to parameters
+
+ raise `NoSelectableObject` if not object apply
+ """
+ if len(args) > 1:
+ warn('only the request param can not be named when calling select',
+ DeprecationWarning, stacklevel=2)
+ score, winners = 0, []
+ for vobject in vobjects:
+ vobjectscore = vobject.__select__(vobject, *args, **kwargs)
+ if vobjectscore > score:
+ score, winners = vobjectscore, [vobject]
+ elif vobjectscore > 0 and vobjectscore == score:
+ winners.append(vobject)
+ if not winners:
+ raise NoSelectableObject('args: %s\nkwargs: %s %s'
+ % (args, kwargs.keys(),
+ [repr(v) for v in vobjects]))
+ if len(winners) > 1:
+ if self.config.mode == 'installed':
+ self.error('select ambiguity, args: %s\nkwargs: %s %s',
+ args, kwargs.keys(), [repr(v) for v in winners])
+ else:
+ raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
+ % (args, kwargs.keys(),
+ [repr(v) for v in winners]))
+ # return the result of the .selected method of the vobject
+ return winners[0].selected(*args, **kwargs)
+
# methods for explicit (un)registration ###################################
# def clear(self, key):
# regname, oid = key.split('.')
# self[regname].pop(oid, None)
+
def register_all(self, objects, modname, butclasses=()):
for obj in objects:
try:
@@ -262,52 +329,6 @@
replaced, obj)
self.register(obj, registryname=registryname)
- # dynamic selection methods ###############################################
-
- def select(self, vobjects, *args, **kwargs):
- """return an instance of the most specific object according
- to parameters
-
- raise NoSelectableObject if not object apply
- """
- score, winners = 0, []
- for vobject in vobjects:
- vobjectscore = vobject.__select__(vobject, *args, **kwargs)
- if vobjectscore > score:
- score, winners = vobjectscore, [vobject]
- elif vobjectscore > 0 and vobjectscore == score:
- winners.append(vobject)
- if not winners:
- raise NoSelectableObject('args: %s\nkwargs: %s %s'
- % (args, kwargs.keys(),
- [repr(v) for v in vobjects]))
- if len(winners) > 1:
- if self.config.mode == 'installed':
- self.error('select ambiguity, args: %s\nkwargs: %s %s',
- args, kwargs.keys(), [repr(v) for v in winners])
- else:
- raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
- % (args, kwargs.keys(),
- [repr(v) for v in winners]))
- winner = winners[0]
- # return the result of the .selected method of the vobject
- return winner.selected(*args, **kwargs)
-
- def possible_objects(self, registry, *args, **kwargs):
- """return an iterator on possible objects in a registry for this result set
-
- actions returned are classes, not instances
- """
- for vobjects in self.registry(registry).values():
- try:
- yield self.select(vobjects, *args, **kwargs)
- except NoSelectableObject:
- continue
-
- def select_object(self, registry, cid, *args, **kwargs):
- """return the most specific component according to the resultset"""
- return self.select(self.registry_objects(registry, cid), *args, **kwargs)
-
# intialization methods ###################################################
def init_registration(self, path, extrapath=None):
--- a/web/application.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/application.py Thu Jul 02 10:35:03 2009 +0200
@@ -10,21 +10,25 @@
import sys
from time import clock, time
+from logilab.common.deprecation import obsolete
+
from rql import BadRQLQuery
-from cubicweb import set_log_methods
-from cubicweb import (ValidationError, Unauthorized, AuthenticationError,
- NoSelectableObject, RepositoryError)
-from cubicweb.cwvreg import CubicWebRegistry
-from cubicweb.web import (LOGGER, StatusResponse, DirectResponse, Redirect, NotFound,
- RemoteCallFailed, ExplicitLogin, InvalidSession)
+from cubicweb import set_log_methods, cwvreg
+from cubicweb import (
+ ValidationError, Unauthorized, AuthenticationError, NoSelectableObject,
+ RepositoryError)
+from cubicweb.web import LOGGER, component
+from cubicweb.web import (
+ StatusResponse, DirectResponse, Redirect, NotFound,
+ RemoteCallFailed, ExplicitLogin, InvalidSession)
from cubicweb.web.component import Component
# make session manager available through a global variable so the debug view can
# print information about web session
SESSION_MANAGER = None
-class AbstractSessionManager(Component):
+class AbstractSessionManager(component.Component):
"""manage session data associated to a session identifier"""
id = 'sessionmanager'
@@ -38,8 +42,7 @@
if self.session_time:
assert self.cleanup_session_time < self.session_time
assert self.cleanup_anon_session_time < self.session_time
- self.authmanager = self.vreg.select_component('authmanager')
- assert self.authmanager, 'no authentication manager found'
+ self.authmanager = self.vreg.select('components', 'authmanager')
def clean_sessions(self):
"""cleanup sessions which has not been unused since a given amount of
@@ -87,7 +90,7 @@
raise NotImplementedError()
-class AbstractAuthenticationManager(Component):
+class AbstractAuthenticationManager(component.Component):
"""authenticate user associated to a request and check session validity"""
id = 'authmanager'
@@ -110,8 +113,7 @@
SESSION_VAR = '__session'
def __init__(self, appli):
- self.session_manager = appli.vreg.select_component('sessionmanager')
- assert self.session_manager, 'no session manager found'
+ self.session_manager = appli.vreg.select('components', 'sessionmanager')
global SESSION_MANAGER
SESSION_MANAGER = self.session_manager
if not 'last_login_time' in appli.vreg.schema:
@@ -209,20 +211,8 @@
class CubicWebPublisher(object):
- """Central registry for the web application. This is one of the central
- object in the web application, coupling dynamically loaded objects with
- the application's schema and the application's configuration objects.
-
- It specializes the VRegistry by adding some convenience methods to
- access to stored objects. Currently we have the following registries
- of objects known by the web application (library may use some others
- additional registries):
- * controllers, which are directly plugged into the application
- object to handle request publishing
- * views
- * templates
- * components
- * actions
+ """the publisher is a singleton hold by the web frontend, and is responsible
+ to publish HTTP request.
"""
def __init__(self, config, debug=None,
@@ -231,7 +221,7 @@
super(CubicWebPublisher, self).__init__()
# connect to the repository and get application's schema
if vreg is None:
- vreg = CubicWebRegistry(config, debug=debug)
+ vreg = cwvreg.CubicWebRegistry(config, debug=debug)
self.vreg = vreg
self.info('starting web application from %s', config.apphome)
self.repo = config.repository(vreg)
@@ -250,7 +240,7 @@
self.publish = self.main_publish
# instantiate session and url resolving helpers
self.session_handler = session_handler_fact(self)
- self.url_resolver = vreg.select_component('urlpublisher')
+ self.url_resolver = vreg.select('components', 'urlpublisher')
def connect(self, req):
"""return a connection for a logged user object according to existing
@@ -259,15 +249,6 @@
"""
self.session_handler.set_session(req)
- def select_controller(self, oid, req):
- """return the most specific view according to the resultset"""
- vreg = self.vreg
- try:
- return vreg.select(vreg.registry_objects('controllers', oid),
- req=req, appli=self)
- except NoSelectableObject:
- raise Unauthorized(req._('not authorized'))
-
# publish methods #########################################################
def log_publish(self, path, req):
@@ -292,6 +273,14 @@
finally:
self._logfile_lock.release()
+ @obsolete("use vreg.select('controllers', ...)")
+ def select_controller(self, oid, req):
+ try:
+ controller = self.vreg.select('controllers', oid, req=req,
+ appli=self)
+ except NoSelectableObject:
+ raise Unauthorized(req._('not authorized'))
+
def main_publish(self, path, req):
"""method called by the main publisher to process <path>
@@ -316,7 +305,11 @@
try:
try:
ctrlid, rset = self.url_resolver.process(req, path)
- controller = self.select_controller(ctrlid, req)
+ try:
+ controller = self.vreg.select('controllers', ctrlid, req,
+ appli=self)
+ except NoSelectableObject:
+ raise Unauthorized(req._('not authorized'))
req.update_search_state()
result = controller.publish(rset=rset)
if req.cnx is not None:
@@ -384,7 +377,7 @@
if tb:
req.data['excinfo'] = excinfo
req.form['vid'] = 'error'
- errview = self.vreg.select_view('error', req, None)
+ errview = self.vreg.select('views', 'error', req)
template = self.main_template_id(req)
content = self.vreg.main_template(req, template, view=errview)
except:
@@ -399,7 +392,7 @@
def notfound_content(self, req):
req.form['vid'] = '404'
- view = self.vreg.select_view('404', req, None)
+ view = self.vreg.select('views', '404', req)
template = self.main_template_id(req)
return self.vreg.main_template(req, template, view=view)
--- a/web/box.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/box.py Thu Jul 02 10:35:03 2009 +0200
@@ -219,8 +219,8 @@
return entity.unrelated(self.rtype, self.etype, get_role(self)).entities()
# in other cases, use vocabulary functions
entities = []
- form = self.vreg.select_object('forms', 'edition', self.req, self.rset,
- row=self.row or 0)
+ form = self.vreg.select('forms', 'edition', self.req, rset=self.rset,
+ row=self.row or 0)
field = form.field_by_name(self.rtype, get_role(self), entity.e_schema)
for _, eid in form.form_field_vocabulary(field):
if eid is not None:
--- a/web/component.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/component.py Thu Jul 02 10:35:03 2009 +0200
@@ -6,6 +6,7 @@
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
+_ = unicode
from logilab.common.deprecation import class_renamed
from logilab.mtconverter import html_escape
@@ -18,7 +19,6 @@
partial_has_related_entities, condition_compat, accepts_compat,
has_relation_compat)
-_ = unicode
class EntityVComponent(Component):
"""abstract base class for additinal components displayed in content
--- a/web/controller.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/controller.py Thu Jul 02 10:35:03 2009 +0200
@@ -86,14 +86,16 @@
def process_rql(self, rql):
"""execute rql if specified"""
+ # XXX assigning to self really necessary?
+ self.rset = None
if rql:
self.ensure_ro_rql(rql)
if not isinstance(rql, unicode):
rql = unicode(rql, self.req.encoding)
- pp = self.vreg.select_component('magicsearch', self.req)
- self.rset = pp.process_query(rql, self.req)
- return self.rset
- return None
+ pp = self.vreg.select_object('components', 'magicsearch', self.req)
+ if pp is not None:
+ self.rset = pp.process_query(rql, self.req)
+ return self.rset
def check_expected_params(self, params):
"""check that the given list of parameters are specified in the form
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/data/jquery.tools.min.js Thu Jul 02 10:35:03 2009 +0200
@@ -0,0 +1,20 @@
+/*
+ * jquery.tools 1.0.2 - The missing UI library
+ *
+ * [tools.tabs-1.0.1, tools.tooltip-1.0.2, tools.scrollable-1.0.5, tools.overlay-1.0.4, tools.expose-1.0.3]
+ *
+ * Copyright (c) 2009 Tero Piirainen
+ * http://flowplayer.org/tools/
+ *
+ * Dual licensed under MIT and GPL 2+ licenses
+ * http://www.opensource.org/licenses
+ *
+ * -----
+ *
+ * Build: Fri Jun 12 12:37:07 GMT+00:00 2009
+ */
+(function(c){c.tools=c.tools||{version:{}};c.tools.version.tabs="1.0.1";c.tools.addTabEffect=function(d,e){b[d]=e};var b={"default":function(d){this.getPanes().hide().eq(d).show()},fade:function(d){this.getPanes().hide().eq(d).fadeIn(this.getConf().fadeInSpeed)},slide:function(d){this.getCurrentPane().slideUp("fast");this.getPanes().eq(d).slideDown()},horizontal:function(d){if(!c._hW){c._hW=this.getPanes().eq(0).width()}this.getCurrentPane().animate({width:0},function(){c(this).hide()});this.getPanes().eq(d).animate({width:c._hW},function(){c(this).show()})}};function a(e,f,g){var d=this;var h;function i(j,k){c(d).bind(j,function(m,l){if(k&&k.call(this,l.index)===false&&l){l.proceed=false}});return d}c.each(g,function(j,k){if(c.isFunction(k)){i(j,k)}});c.extend(this,{click:function(k){if(k===h){return d}var m=d.getCurrentPane();var l=e.eq(k);if(typeof k=="string"){l=e.filter("[href="+k+"]");k=e.index(l)}if(!l.length){if(h>=0){return d}k=g.initialIndex;l=e.eq(k)}var j={index:k,proceed:true};c(d).triggerHandler("onBeforeClick",j);if(!j.proceed){return d}l.addClass(g.current);b[g.effect].call(d,k);c(d).triggerHandler("onClick",j);e.removeClass(g.current);l.addClass(g.current);h=k;return d},getConf:function(){return g},getTabs:function(){return e},getPanes:function(){return f},getCurrentPane:function(){return f.eq(h)},getCurrentTab:function(){return e.eq(h)},getIndex:function(){return h},next:function(){return d.click(h+1)},prev:function(){return d.click(h-1)},onBeforeClick:function(j){return i("onBeforeClick",j)},onClick:function(j){return i("onClick",j)}});e.each(function(j){c(this).bind(g.event,function(k){d.click(j);if(!g.history){return k.preventDefault()}})});if(g.history){e.history(function(j,k){d.click(k||0)})}if(location.hash){d.click(location.hash)}else{d.click(g.initialIndex)}f.find("a[href^=#]").click(function(){d.click(c(this).attr("href"))})}c.fn.tabs=function(g,d){var e=this.eq(typeof conf=="number"?conf:0).data("tabs");if(e){return e}var f={tabs:"a",current:"current",onBeforeClick:null,onClick:null,effect:"default",history:false,initialIndex:0,event:"click",api:false};if(c.isFunction(d)){d={onBeforeClick:d}}c.extend(f,d);this.each(function(){var h=c(this).find(f.tabs);if(!h.length){h=c(this).children()}var i=g.jquery?g:c(g);e=new a(h,i,f);c(this).data("tabs",e)});return f.api?e:this}})(jQuery);(function(b){var c,a;b.prototype.history=function(e){var d=this;if(b.browser.msie){if(!a){a=b("<iframe />").hide().get(0);b("body").append(a);setInterval(function(){var f=a.contentWindow.document;var g=f.location.hash;if(c!==g){b.event.trigger("hash",g);c=g}},100)}d.bind("click.hash",function(g){var f=a.contentWindow.document;f.open().close();f.location.hash=b(this).attr("href")});d.eq(0).triggerHandler("click.hash")}else{setInterval(function(){var f=location.hash;if(d.filter("[href*="+f+"]").length&&f!==c){c=f;b.event.trigger("hash",f)}},100)}b(window).bind("hash",e);return this}})(jQuery);
+(function(c){c.tools=c.tools||{version:{}};c.tools.version.tooltip="1.0.2";var b={toggle:[function(){this.getTip().show()},function(){this.getTip().hide()}],fade:[function(){this.getTip().fadeIn(this.getConf().fadeInSpeed)},function(){this.getTip().fadeOut(this.getConf().fadeOutSpeed)}]};c.tools.addTipEffect=function(d,f,e){b[d]=[f,e]};c.tools.addTipEffect("slideup",function(){var d=this.getConf();var e=d.slideOffset||10;this.getTip().css({opacity:0}).animate({top:"-="+e,opacity:d.opacity},d.slideInSpeed||200).show()},function(){var d=this.getConf();var e=d.slideOffset||10;this.getTip().animate({top:"-="+e,opacity:0},d.slideOutSpeed||200,function(){c(this).hide().animate({top:"+="+(e*2)},0)})});function a(f,e){var d=this;var h=f.next();if(e.tip){if(e.tip.indexOf("#")!=-1){h=c(e.tip)}else{h=f.nextAll(e.tip).eq(0);if(!h.length){h=f.parent().nextAll(e.tip).eq(0)}}}function j(k,l){c(d).bind(k,function(n,m){if(l&&l.call(this)===false&&m){m.proceed=false}});return d}c.each(e,function(k,l){if(c.isFunction(l)){j(k,l)}});var g=f.is("input, textarea");f.bind(g?"focus":"mouseover",function(k){k.target=this;d.show(k);h.hover(function(){d.show()},function(){d.hide()})});f.bind(g?"blur":"mouseout",function(){d.hide()});h.css("opacity",e.opacity);var i=0;c.extend(d,{show:function(q){if(q){f=c(q.target)}clearTimeout(i);if(h.is(":animated")||h.is(":visible")){return d}var o={proceed:true};c(d).trigger("onBeforeShow",o);if(!o.proceed){return d}var n=f.position().top-h.outerHeight();var k=h.outerHeight()+f.outerHeight();var r=e.position[0];if(r=="center"){n+=k/2}if(r=="bottom"){n+=k}var l=f.outerWidth()+h.outerWidth();var m=f.position().left+f.outerWidth();r=e.position[1];if(r=="center"){m-=l/2}if(r=="left"){m-=l}n+=e.offset[0];m+=e.offset[1];h.css({position:"absolute",top:n,left:m});b[e.effect][0].call(d);c(d).trigger("onShow");return d},hide:function(){clearTimeout(i);i=setTimeout(function(){if(!h.is(":visible")){return d}var k={proceed:true};c(d).trigger("onBeforeHide",k);if(!k.proceed){return d}b[e.effect][1].call(d);c(d).trigger("onHide")},e.delay||1);return d},isShown:function(){return h.is(":visible, :animated")},getConf:function(){return e},getTip:function(){return h},getTrigger:function(){return f},onBeforeShow:function(k){return j("onBeforeShow",k)},onShow:function(k){return j("onShow",k)},onBeforeHide:function(k){return j("onBeforeHide",k)},onHide:function(k){return j("onHide",k)}})}c.prototype.tooltip=function(d){var e=this.eq(typeof d=="number"?d:0).data("tooltip");if(e){return e}var f={tip:null,effect:"slideup",delay:30,opacity:1,position:["top","center"],offset:[0,0],api:false};if(c.isFunction(d)){d={onBeforeShow:d}}c.extend(f,d);this.each(function(){e=new a(c(this),f);c(this).data("tooltip",e)});return f.api?e:this}})(jQuery);
+(function(b){b.tools=b.tools||{version:{}};b.tools.version.scrollable="1.0.5";var c=null;function a(p,m){var s=this;if(!c){c=s}function n(t,u){b(s).bind(t,function(w,v){if(u&&u.call(this,v.index)===false&&v){v.proceed=false}});return s}b.each(m,function(t,u){if(b.isFunction(u)){n(t,u)}});var d=!m.vertical;var f=b(m.items,p);var j=0;function l(u,t){return u.indexOf("#")!=-1?b(u).eq(0):t.siblings(u).eq(0)}var q=l(m.navi,p);var g=l(m.prev,p);var i=l(m.next,p);var h=l(m.prevPage,p);var o=l(m.nextPage,p);b.extend(s,{getIndex:function(){return j},getConf:function(){return m},getSize:function(){return s.getItems().size()},getPageAmount:function(){return Math.ceil(this.getSize()/m.size)},getPageIndex:function(){return Math.ceil(j/m.size)},getRoot:function(){return p},getItemWrap:function(){return f},getItems:function(){return f.children()},getVisibleItems:function(){return s.getItems().slice(j,j+m.size)},seekTo:function(w,u,A){if(u===undefined){u=m.speed}if(b.isFunction(u)){A=u;u=m.speed}if(w<0){w=0}if(w>s.getSize()-m.size){return s}var B=s.getItems().eq(w);if(!B.length){return s}var t={index:w,proceed:true};b(s).trigger("onBeforeSeek",t);if(!t.proceed){return s}if(d){var v=-B.position().left;f.animate({left:v},u,m.easing,A?function(){A.call(s)}:null)}else{var z=-B.position().top;f.animate({top:z},u,m.easing,A?function(){A.call(s)}:null)}if(q.length){var x=m.activeClass;var y=Math.ceil(w/m.size);y=Math.min(y,q.children().length-1);q.children().removeClass(x).eq(y).addClass(x)}if(w===0){g.add(h).addClass(m.disabledClass)}else{g.add(h).removeClass(m.disabledClass)}if(w>=s.getSize()-m.size){i.add(o).addClass(m.disabledClass)}else{i.add(o).removeClass(m.disabledClass)}c=s;j=w;b(s).trigger("onSeek",{index:w});return s},move:function(v,u,t){var w=j+v;if(m.loop&&w>(s.getSize()-m.size)){w=0}return this.seekTo(w,u,t)},next:function(u,t){return this.move(1,u,t)},prev:function(u,t){return this.move(-1,u,t)},movePage:function(v,u,t){return this.move(m.size*v,u,t)},setPage:function(x,y,v){var u=m.size;var t=u*x;var w=t+u>=this.getSize();if(w){t=this.getSize()-m.size}return this.seekTo(t,y,v)},prevPage:function(u,t){return this.setPage(this.getPageIndex()-1,u,t)},nextPage:function(u,t){return this.setPage(this.getPageIndex()+1,u,t)},begin:function(u,t){return this.seekTo(0,u,t)},end:function(u,t){return this.seekTo(this.getSize()-m.size,u,t)},reload:function(){return r()},click:function(u,x,v){var w=s.getItems().eq(u);var t=m.activeClass;if(u<0||u>=this.getSize()){return s}if(m.size==2){if(u==s.getIndex()){u--}s.getItems().removeClass(t);w.addClass(t);return this.seekTo(u,x,v)}if(!w.hasClass(t)){s.getItems().removeClass(t);w.addClass(t);var z=Math.floor(m.size/2);var y=u-z;if(y>s.getSize()-m.size){y=s.getSize()-m.size}if(y!==u){return this.seekTo(y,x,v)}}return s},onBeforeSeek:function(t){return n("onBeforeSeek",t)},onSeek:function(t){return n("onSeek",t)}});if(b.isFunction(b.fn.mousewheel)){p.bind("mousewheel.scrollable",function(u,v){var t=b.browser.opera?1:-1;s.move(v>0?t:-t,50);return false})}g.addClass(m.disabledClass).click(function(){s.prev()});i.click(function(){s.next()});o.click(function(){s.nextPage()});h.addClass(m.disabledClass).click(function(){s.prevPage()});if(m.keyboard){b(document).unbind("keydown.scrollable").bind("keydown.scrollable",function(t){var u=c;if(!u||t.altKey||t.ctrlKey){return}if(d&&(t.keyCode==37||t.keyCode==39)){u.move(t.keyCode==37?-1:1);return t.preventDefault()}if(!d&&(t.keyCode==38||t.keyCode==40)){u.move(t.keyCode==38?-1:1);return t.preventDefault()}return true})}function r(){if(q.is(":empty")||q.data("me")==s){q.empty();q.data("me",s);for(var u=0;u<s.getPageAmount();u++){var v=b("<"+m.naviItem+"/>").attr("href",u).click(function(x){var w=b(this);w.parent().children().removeClass(m.activeClass);w.addClass(m.activeClass);s.setPage(w.attr("href"));return x.preventDefault()});if(u===0){v.addClass(m.activeClass)}q.append(v)}}else{var t=q.children();t.each(function(w){var x=b(this);x.attr("href",w);if(w===0){x.addClass(m.activeClass)}x.click(function(){q.find("."+m.activeClass).removeClass(m.activeClass);x.addClass(m.activeClass);s.setPage(x.attr("href"))})})}if(m.clickable){s.getItems().each(function(x,w){var y=b(this);if(!y.data("set")){y.bind("click.scrollable",function(){s.click(x)});y.data("set",true)}})}if(m.hoverClass){s.getItems().hover(function(){b(this).addClass(m.hoverClass)},function(){b(this).removeClass(m.hoverClass)})}return s}r();var e=null;function k(){if(e){return}e=setInterval(function(){if(m.interval===0){clearInterval(e);e=0;return}s.next()},m.interval)}if(m.interval>0){p.hover(function(){clearInterval(e);e=0},function(){k()});k()}}b.fn.scrollable=function(d){var e=this.eq(typeof d=="number"?d:0).data("scrollable");if(e){return e}var f={size:5,vertical:false,clickable:true,loop:false,interval:0,speed:400,keyboard:true,activeClass:"active",disabledClass:"disabled",hoverClass:null,easing:"swing",items:".items",prev:".prev",next:".next",prevPage:".prevPage",nextPage:".nextPage",navi:".navi",naviItem:"a",api:false,onBeforeSeek:null,onSeek:null};b.extend(f,d);this.each(function(){e=new a(b(this),f);b(this).data("scrollable",e)});return f.api?e:this}})(jQuery);
+(function(b){b.tools=b.tools||{version:{}};b.tools.version.overlay="1.0.4";var c=[];function a(h,d){var r=this,q=b(window),f,n,s,i,k,m,l;var e=d.expose&&b.tools.version.expose;function p(o,t){b(r).bind(o,function(v,u){if(t&&t.call(this)===false&&u){u.proceed=false}});return r}b.each(d,function(o,t){if(b.isFunction(t)){p(o,t)}});var j=d.target||h.attr("rel");var g=j?b(j):null;if(!g){g=h}else{k=h}q.load(function(){m=g.attr("overlay");if(!m){m=g.css("backgroundImage");if(!m){throw"background-image CSS property not set for overlay element: "+j}m=m.substring(m.indexOf("(")+1,m.indexOf(")")).replace(/\"/g,"");g.css("backgroundImage","none");g.attr("overlay",m)}s=g.outerWidth({margin:true});i=g.outerHeight({margin:true});n=b('<img src="'+m+'"/>');n.css({border:0,position:"absolute",display:"none"}).width(s).attr("overlay",true);b("body").append(n);if(k){k.bind("click.overlay",function(o){r.load(o.pageY-q.scrollTop(),o.pageX-q.scrollLeft());return o.preventDefault()})}d.close=d.close||".close";if(!g.find(d.close).length){g.prepend('<div class="close"></div>')}f=g.find(d.close);f.bind("click.overlay",function(){r.close()});if(d.preload){setTimeout(function(){var o=new Image();o.src=m},2000)}});b.extend(r,{load:function(w,v){if(!n){q.load(function(){r.load(w,v)});return r}if(r.isOpened()){return r}if(d.oneInstance){b.each(c,function(){this.close()})}var u={proceed:true};b(r).trigger("onBeforeLoad",u);if(!u.proceed){return r}if(e){n.expose(d.expose);l=n.expose().load()}w=w||d.start.top;v=v||d.start.left;var o=d.finish.top;var t=d.finish.left;if(o=="center"){o=Math.max((q.height()-i)/2,0)}if(t=="center"){t=Math.max((q.width()-s)/2,0)}if(!d.start.absolute){w+=q.scrollTop();v+=q.scrollLeft()}if(!d.finish.absolute){o+=q.scrollTop();t+=q.scrollLeft()}n.css({top:w,left:v,width:d.start.width,zIndex:d.zIndex}).show();n.animate({top:o,left:t,width:s},d.speed,function(){g.css({position:"absolute",top:o,left:t});var x=n.css("zIndex");f.add(g).css("zIndex",++x);g.fadeIn(d.fadeInSpeed,function(){b(r).trigger("onLoad")})});return r},close:function(){if(!r.isOpened()){return r}var u={proceed:true};b(r).trigger("onBeforeClose",u);if(!u.proceed){return r}if(l){l.close()}if(n.is(":visible")){g.hide();var t=d.start.top;var o=d.start.left;if(k){u=k.offset();t=u.top+k.height()/2;o=u.left+k.width()/2}n.animate({top:t,left:o,width:0},d.closeSpeed,function(){b(r).trigger("onClose",u)})}return r},getBackgroundImage:function(){return n},getContent:function(){return g},getTrigger:function(){return k},isOpened:function(){return g.is(":visible")},getConf:function(){return d},onBeforeLoad:function(o){return p("onBeforeLoad",o)},onLoad:function(o){return p("onLoad",o)},onBeforeClose:function(o){return p("onBeforeClose",o)},onClose:function(o){return p("onClose",o)}});b(document).keydown(function(o){if(o.keyCode==27){r.close()}});if(d.closeOnClick){b(document).bind("click.overlay",function(o){if(!g.is(":visible, :animated")){return}var t=b(o.target);if(t.attr("overlay")){return}if(t.parents("[overlay]").length){return}r.close()})}}b.fn.overlay=function(e){var f=this.eq(typeof e=="number"?e:0).data("overlay");if(f){return f}var d=b(window);var g={start:{top:Math.round(d.height()/2),left:Math.round(d.width()/2),width:0,absolute:false},finish:{top:80,left:"center",absolute:false},speed:"normal",fadeInSpeed:"fast",closeSpeed:"fast",close:null,oneInstance:true,closeOnClick:true,preload:true,zIndex:9999,api:false,expose:null,target:null};if(b.isFunction(e)){e={onBeforeLoad:e}}b.extend(true,g,e);this.each(function(){f=new a(b(this),g);c.push(f);b(this).data("overlay",f)});return g.api?f:this}})(jQuery);
+(function(b){b.tools=b.tools||{version:{}};b.tools.version.expose="1.0.3";function a(){var e=b(window).width();if(b.browser.mozilla){return e}var d;if(window.innerHeight&&window.scrollMaxY){d=window.innerWidth+window.scrollMaxX}else{if(document.body.scrollHeight>document.body.offsetHeight){d=document.body.scrollWidth}else{d=document.body.offsetWidth}}return d<e?d+20:e}function c(g,h){var e=this,d=null,f=false,i=0;function j(k,l){b(e).bind(k,function(n,m){if(l&&l.call(this)===false&&m){m.proceed=false}});return e}b.each(h,function(k,l){if(b.isFunction(l)){j(k,l)}});b(window).bind("resize.expose",function(){if(d){d.css({width:a(),height:b(document).height()})}});b.extend(this,{getMask:function(){return d},getExposed:function(){return g},getConf:function(){return h},isLoaded:function(){return f},load:function(){if(f){return e}i=g.eq(0).css("zIndex");if(h.maskId){d=b("#"+h.maskId)}if(!d||!d.length){d=b("<div/>").css({position:"absolute",top:0,left:0,width:a(),height:b(document).height(),display:"none",opacity:0,zIndex:h.zIndex});if(h.maskId){d.attr("id",h.maskId)}b("body").append(d);var k=d.css("backgroundColor");if(!k||k=="transparent"||k=="rgba(0, 0, 0, 0)"){d.css("backgroundColor",h.color)}if(h.closeOnEsc){b(document).bind("keydown.unexpose",function(n){if(n.keyCode==27){e.close()}})}if(h.closeOnClick){d.bind("click.unexpose",function(){e.close()})}}var m={proceed:true};b(e).trigger("onBeforeLoad",m);if(!m.proceed){return e}b.each(g,function(){var n=b(this);if(!/relative|absolute|fixed/i.test(n.css("position"))){n.css("position","relative")}});g.css({zIndex:h.zIndex+1});var l=d.height();if(!this.isLoaded()){d.css({opacity:0,display:"block"}).fadeTo(h.loadSpeed,h.opacity,function(){if(d.height()!=l){d.css("height",l)}b(e).trigger("onLoad")})}f=true;return e},close:function(){if(!f){return e}var k={proceed:true};b(e).trigger("onBeforeClose",k);if(k.proceed===false){return e}d.fadeOut(h.closeSpeed,function(){b(e).trigger("onClose");g.css({zIndex:b.browser.msie?i:null})});f=false;return e},onBeforeLoad:function(k){return j("onBeforeLoad",k)},onLoad:function(k){return j("onLoad",k)},onBeforeClose:function(k){return j("onBeforeClose",k)},onClose:function(k){return j("onClose",k)}})}b.fn.expose=function(d){var e=this.eq(typeof d=="number"?d:0).data("expose");if(e){return e}var f={maskId:null,loadSpeed:"slow",closeSpeed:"fast",closeOnClick:true,closeOnEsc:true,zIndex:9998,opacity:0.8,color:"#456",api:false};if(typeof d=="string"){d={color:d}}b.extend(f,d);this.each(function(){e=new c(b(this),f);b(this).data("expose",e)});return f.api?e:this}})(jQuery);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/data/tabs-no-images.css Thu Jul 02 10:35:03 2009 +0200
@@ -0,0 +1,62 @@
+
+/* root element for tabs */
+ul.css-tabs {
+ margin:0 !important;
+ padding:0;
+ height:24px;
+ border-bottom:1px solid #666;
+}
+
+/* single tab */
+ul.css-tabs li {
+ float:left;
+ padding:0;
+ margin:0;
+ list-style-type:none;
+}
+
+/* link inside the tab. uses a background image */
+ul.css-tabs a {
+ float:left;
+ font-size:12px;
+ display:block;
+ padding:2px 20px;
+ text-decoration:none;
+ border:1px solid #666;
+ border-bottom:0px;
+ height:18px;
+ background-color:#efefef;
+ color:#777;
+ margin-right:2px;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright:4px;
+ position:relative;
+ top:1px;
+}
+
+ul.css-tabs a:hover {
+ background-color:#CFCEB7;
+ color:#333;
+}
+
+/* selected tab */
+ul.css-tabs a.current {
+ background-color: white;
+ border-bottom:2px solid #ddd;
+ color:#000;
+ cursor:default;
+}
+
+
+/* tab pane */
+div.css-panes div {
+ display:none;
+ border:1px solid #666;
+ border-width:0 1px 1px 1px;
+ min-height:150px;
+ padding:15px 20px;
+ /* background-color:#ddd; */
+}
+
+
+
--- a/web/data/ui.tabs.css Thu Jul 02 10:30:44 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/* Caution! Ensure accessibility in print and other media types... */
-@media projection, screen { /* Use class for showing/hiding tab content, so that visibility can be better controlled in different media types... */
- .ui-tabs-hide {
- display: none;
- }
-}
-
-/* Hide useless elements in print layouts... */
-@media print {
- .ui-tabs-nav {
- display: none;
- }
-}
-
-/* Skin */
-.ui-tabs-nav, .ui-tabs-panel {
- font-family: "Trebuchet MS", Trebuchet, Verdana, Helvetica, Arial, sans-serif;
- font-size: 12px;
-
-}
-.ui-tabs-nav {
- list-style: none;
- margin: 0px;
- padding: 0px 0px 0px 4px;
-
-}
-.ui-tabs-nav:after { /* clearing without presentational markup, IE gets extra treatment */
- display: block;
- clear: both;
- content: " ";
-}
-.ui-tabs-nav li {
- float: left;
- margin: 0 0 0 1px;
- min-width: 84px; /* be nice to Opera */
- list-style: none;
- background: none;
- padding: 0px 0px 1px 1px;
-}
-.ui-tabs-nav a, .ui-tabs-nav a span {
- display: block;
- padding: 0 10px;
- background: url(tab.png) no-repeat;
-}
-.ui-tabs-nav a {
- margin: 1px 0 0; /* position: relative makes opacity fail for disabled tab in IE */
- padding-left: 0;
- color: #27537a;
- font-weight: bold;
- line-height: 1.2;
- text-align: center;
- text-decoration: none;
- white-space: nowrap; /* required in IE 6 */
- outline: 0; /* prevent dotted border in Firefox */
-}
-.ui-tabs-nav .ui-tabs-selected a {
- position: relative;
- top: 1px;
- z-index: 2;
- margin-top: 0;
- color: #000;
-}
-.ui-tabs-nav a span {
- width: 64px; /* IE 6 treats width as min-width */
- min-width: 64px;
- height: 18px; /* IE 6 treats height as min-height */
- min-height: 18px;
- padding-top: 6px;
- padding-right: 0;
-}
-*>.ui-tabs-nav a span { /* hide from IE 6 */
- width: auto;
- height: auto;
-}
-.ui-tabs-nav .ui-tabs-selected a span {
- padding-bottom: 1px;
-}
-.ui-tabs-nav .ui-tabs-selected a, .ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active {
- background-position: 100% -150px;
-}
-.ui-tabs-nav a, .ui-tabs-nav .ui-tabs-disabled a:hover, .ui-tabs-nav .ui-tabs-disabled a:focus, .ui-tabs-nav .ui-tabs-disabled a:active {
- background-position: 100% -100px;
-}
-.ui-tabs-nav .ui-tabs-selected a span, .ui-tabs-nav a:hover span, .ui-tabs-nav a:focus span, .ui-tabs-nav a:active span {
- background-position: 0 -50px;
-}
-.ui-tabs-nav a span, .ui-tabs-nav .ui-tabs-disabled a:hover span, .ui-tabs-nav .ui-tabs-disabled a:focus span, .ui-tabs-nav .ui-tabs-disabled a:active span {
- background-position: 0 0;
-}
-.ui-tabs-nav .ui-tabs-selected a:link, .ui-tabs-nav .ui-tabs-selected a:visited, .ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { /* @ Opera, use pseudo classes otherwise it confuses cursor... */
- cursor: text;
-}
-.ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active,
-.ui-tabs-nav .ui-tabs-unselect a:hover, .ui-tabs-nav .ui-tabs-unselect a:focus, .ui-tabs-nav .ui-tabs-unselect a:active { /* @ Opera, we need to be explicit again here now... */
- cursor: pointer;
-}
-.ui-tabs-disabled {
- opacity: .4;
- filter: alpha(opacity=40);
-}
-.ui-tabs-panel {
- border-top: 1px solid #97a5b0;
- padding: 1em 8px;
- margin-top:-1px; /* Logilab style */
- background: #fff; /* declare background color for container to avoid distorted fonts in IE while fading */
-}
-.ui-tabs-loading em {
- padding: 0 0 0 20px;
- background: url(loading.gif) no-repeat 0 50%;
-}
-
-/* Additional IE specific bug fixes... */
-* html .ui-tabs-nav { /* auto clear, @ IE 6 & IE 7 Quirks Mode */
- display: inline-block;
-}
-*:first-child+html .ui-tabs-nav { /* @ IE 7 Standards Mode - do not group selectors, otherwise IE 6 will ignore complete rule (because of the unknown + combinator)... */
- display: inline-block;
-}
-
-/* ========= Lobilab styles =========== */
-
-/* added by katia */
-* html .ui-tabs-panel{
- width:100%;
-}
\ No newline at end of file
--- a/web/data/ui.tabs.js Thu Jul 02 10:30:44 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,587 +0,0 @@
-/*
- * jQuery UI Tabs @VERSION
- *
- * Copyright (c) 2007, 2008 Klaus Hartl (stilbuero.de)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * http://docs.jquery.com/UI/Tabs
- *
- * Depends:
- * ui.core.js
- */
-(function($) {
-
-$.widget("ui.tabs", {
- _init: function() {
- this.options.event += '.tabs'; // namespace event
-
- // create tabs
- this._tabify(true);
- },
- _setData: function(key, value) {
- if ((/^selected/).test(key))
- this.select(value);
- else {
- this.options[key] = value;
- this._tabify();
- }
- },
- length: function() {
- return this.$tabs.length;
- },
- _tabId: function(a) {
- return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '')
- || this.options.idPrefix + $.data(a);
- },
- ui: function(tab, panel) {
- return {
- options: this.options,
- tab: tab,
- panel: panel,
- index: this.$tabs.index(tab)
- };
- },
- _tabify: function(init) {
-
- this.$lis = $('li:has(a[href])', this.element);
- this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
- this.$panels = $([]);
-
- var self = this, o = this.options;
-
- this.$tabs.each(function(i, a) {
- // inline tab
- if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash
- self.$panels = self.$panels.add(a.hash);
- // remote tab
- else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
- $.data(a, 'href.tabs', a.href); // required for restore on destroy
- $.data(a, 'load.tabs', a.href); // mutable
- var id = self._tabId(a);
- a.href = '#' + id;
- var $panel = $('#' + id);
- if (!$panel.length) {
- $panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
- .insertAfter( self.$panels[i - 1] || self.element );
- $panel.data('destroy.tabs', true);
- }
- self.$panels = self.$panels.add( $panel );
- }
- // invalid tab href
- else
- o.disabled.push(i + 1);
- });
-
- // initialization from scratch
- if (init) {
-
- // attach necessary classes for styling if not present
- this.element.addClass(o.navClass);
- this.$panels.each(function() {
- var $this = $(this);
- $this.addClass(o.panelClass);
- });
-
- // Selected tab
- // use "selected" option or try to retrieve:
- // 1. from fragment identifier in url
- // 2. from cookie
- // 3. from selected class attribute on <li>
- if (o.selected === undefined) {
- if (location.hash) {
- this.$tabs.each(function(i, a) {
- if (a.hash == location.hash) {
- o.selected = i;
- // prevent page scroll to fragment
- if ($.browser.msie || $.browser.opera) { // && !o.remote
- var $toShow = $(location.hash), toShowId = $toShow.attr('id');
- $toShow.attr('id', '');
- setTimeout(function() {
- $toShow.attr('id', toShowId); // restore id
- }, 500);
- }
- scrollTo(0, 0);
- return false; // break
- }
- });
- }
- else if (o.cookie) {
- var index = parseInt($.cookie('ui-tabs-' + $.data(self.element[0])), 10);
- if (index && self.$tabs[index])
- o.selected = index;
- }
- else if (self.$lis.filter('.' + o.selectedClass).length)
- o.selected = self.$lis.index( self.$lis.filter('.' + o.selectedClass)[0] );
- }
- o.selected = o.selected === null || o.selected !== undefined ? o.selected : 0; // first tab selected by default
-
- // Take disabling tabs via class attribute from HTML
- // into account and update option properly.
- // A selected tab cannot become disabled.
- o.disabled = $.unique(o.disabled.concat(
- $.map(this.$lis.filter('.' + o.disabledClass),
- function(n, i) { return self.$lis.index(n); } )
- )).sort();
- if ($.inArray(o.selected, o.disabled) != -1)
- o.disabled.splice($.inArray(o.selected, o.disabled), 1);
-
- // highlight selected tab
- this.$panels.addClass(o.hideClass);
- this.$lis.removeClass(o.selectedClass);
- if (o.selected !== null) {
- this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
- this.$lis.eq(o.selected).addClass(o.selectedClass);
-
- // seems to be expected behavior that the show callback is fired
- var onShow = function() {
- self._trigger('show', null,
- self.ui(self.$tabs[o.selected], self.$panels[o.selected]));
- };
-
- // load if remote tab
- if ($.data(this.$tabs[o.selected], 'load.tabs'))
- this.load(o.selected, onShow);
- // just trigger show event
- else
- onShow();
- }
-
- // clean up to avoid memory leaks in certain versions of IE 6
- $(window).bind('unload', function() {
- self.$tabs.unbind('.tabs');
- self.$lis = self.$tabs = self.$panels = null;
- });
-
- }
- // update selected after add/remove
- else
- o.selected = this.$lis.index( this.$lis.filter('.' + o.selectedClass)[0] );
-
- // set or update cookie after init and add/remove respectively
- if (o.cookie)
- $.cookie('ui-tabs-' + $.data(self.element[0]), o.selected, o.cookie);
-
- // disable tabs
- for (var i = 0, li; li = this.$lis[i]; i++)
- $(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass);
-
- // reset cache if switching from cached to not cached
- if (o.cache === false)
- this.$tabs.removeData('cache.tabs');
-
- // set up animations
- var hideFx, showFx, baseFx = { 'min-width': 0, duration: 1 }, baseDuration = 'normal';
- if (o.fx && o.fx.constructor == Array)
- hideFx = o.fx[0] || baseFx, showFx = o.fx[1] || baseFx;
- else
- hideFx = showFx = o.fx || baseFx;
-
- // reset some styles to maintain print style sheets etc.
- var resetCSS = { display: '', overflow: '', height: '' };
- if (!$.browser.msie) // not in IE to prevent ClearType font issue
- resetCSS.opacity = '';
-
- // Hide a tab, animation prevents browser scrolling to fragment,
- // $show is optional.
- function hideTab(clicked, $hide, $show) {
- $hide.animate(hideFx, hideFx.duration || baseDuration, function() { //
- $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
- if ($.browser.msie && hideFx.opacity)
- $hide[0].style.filter = '';
- if ($show)
- showTab(clicked, $show, $hide);
- });
- }
-
- // Show a tab, animation prevents browser scrolling to fragment,
- // $hide is optional.
- function showTab(clicked, $show, $hide) {
- if (showFx === baseFx)
- $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab panels
- $show.animate(showFx, showFx.duration || baseDuration, function() {
- $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
- if ($.browser.msie && showFx.opacity)
- $show[0].style.filter = '';
-
- // callback
- self._trigger('show', null, self.ui(clicked, $show[0]));
- });
- }
-
- // switch a tab
- function switchTab(clicked, $li, $hide, $show) {
- /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
- $.ajaxHistory.update(clicked.hash);
- }*/
- $li.addClass(o.selectedClass)
- .siblings().removeClass(o.selectedClass);
- hideTab(clicked, $hide, $show);
- }
-
- // attach tab event handler, unbind to avoid duplicates from former tabifying...
- this.$tabs.unbind('.tabs').bind(o.event, function() {
-
- //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
- var $li = $(this).parents('li:eq(0)'),
- $hide = self.$panels.filter(':visible'),
- $show = $(this.hash);
-
- // If tab is already selected and not unselectable or tab disabled or
- // or is already loading or click callback returns false stop here.
- // Check if click handler returns false last so that it is not executed
- // for a disabled or loading tab!
- if (($li.hasClass(o.selectedClass) && !o.unselect)
- || $li.hasClass(o.disabledClass)
- || $(this).hasClass(o.loadingClass)
- || self._trigger('select', null, self.ui(this, $show[0])) === false
- ) {
- this.blur();
- return false;
- }
-
- self.options.selected = self.$tabs.index(this);
-
- // if tab may be closed
- if (o.unselect) {
- if ($li.hasClass(o.selectedClass)) {
- self.options.selected = null;
- $li.removeClass(o.selectedClass);
- self.$panels.stop();
- hideTab(this, $hide);
- this.blur();
- return false;
- } else if (!$hide.length) {
- self.$panels.stop();
- var a = this;
- self.load(self.$tabs.index(this), function() {
- $li.addClass(o.selectedClass).addClass(o.unselectClass);
- showTab(a, $show);
- });
- this.blur();
- return false;
- }
- }
-
- if (o.cookie)
- $.cookie('ui-tabs-' + $.data(self.element[0]), self.options.selected, o.cookie);
-
- // stop possibly running animations
- self.$panels.stop();
-
- // show new tab
- if ($show.length) {
-
- // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
- /*if ($.browser.msie && o.bookmarkable) {
- var showId = this.hash.replace('#', '');
- $show.attr('id', '');
- setTimeout(function() {
- $show.attr('id', showId); // restore id
- }, 0);
- }*/
-
- var a = this;
- self.load(self.$tabs.index(this), $hide.length ?
- function() {
- switchTab(a, $li, $hide, $show);
- } :
- function() {
- $li.addClass(o.selectedClass);
- showTab(a, $show);
- }
- );
-
- // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
- /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
- var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
- setTimeout(function() {
- scrollTo(scrollX, scrollY);
- }, 0);*/
-
- } else
- throw 'jQuery UI Tabs: Mismatching fragment identifier.';
-
- // Prevent IE from keeping other link focussed when using the back button
- // and remove dotted border from clicked link. This is controlled in modern
- // browsers via CSS, also blur removes focus from address bar in Firefox
- // which can become a usability and annoying problem with tabsRotate.
- if ($.browser.msie)
- this.blur();
-
- //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
- return false;
-
- });
-
- // disable click if event is configured to something else
- if (!(/^click/).test(o.event))
- this.$tabs.bind('click.tabs', function() { return false; });
-
- },
- add: function(url, label, index) {
- if (index == undefined)
- index = this.$tabs.length; // append by default
-
- var o = this.options;
- var $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label));
- $li.data('destroy.tabs', true);
-
- var id = url.indexOf('#') == 0 ? url.replace('#', '') : this._tabId( $('a:first-child', $li)[0] );
-
- // try to find an existing element before creating a new one
- var $panel = $('#' + id);
- if (!$panel.length) {
- $panel = $(o.panelTemplate).attr('id', id)
- .addClass(o.hideClass)
- .data('destroy.tabs', true);
- }
- $panel.addClass(o.panelClass);
- if (index >= this.$lis.length) {
- $li.appendTo(this.element);
- $panel.appendTo(this.element[0].parentNode);
- } else {
- $li.insertBefore(this.$lis[index]);
- $panel.insertBefore(this.$panels[index]);
- }
-
- o.disabled = $.map(o.disabled,
- function(n, i) { return n >= index ? ++n : n });
-
- this._tabify();
-
- if (this.$tabs.length == 1) {
- $li.addClass(o.selectedClass);
- $panel.removeClass(o.hideClass);
- var href = $.data(this.$tabs[0], 'load.tabs');
- if (href)
- this.load(index, href);
- }
-
- // callback
- this._trigger('add', null, this.ui(this.$tabs[index], this.$panels[index]));
- },
- remove: function(index) {
- var o = this.options, $li = this.$lis.eq(index).remove(),
- $panel = this.$panels.eq(index).remove();
-
- // If selected tab was removed focus tab to the right or
- // in case the last tab was removed the tab to the left.
- if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1)
- this.select(index + (index + 1 < this.$tabs.length ? 1 : -1));
-
- o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
- function(n, i) { return n >= index ? --n : n });
-
- this._tabify();
-
- // callback
- this._trigger('remove', null, this.ui($li.find('a')[0], $panel[0]));
- },
- enable: function(index) {
- var o = this.options;
- if ($.inArray(index, o.disabled) == -1)
- return;
-
- var $li = this.$lis.eq(index).removeClass(o.disabledClass);
- if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
- $li.css('display', 'inline-block');
- setTimeout(function() {
- $li.css('display', 'block');
- }, 0);
- }
-
- o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });
-
- // callback
- this._trigger('enable', null, this.ui(this.$tabs[index], this.$panels[index]));
- },
- disable: function(index) {
- var self = this, o = this.options;
- if (index != o.selected) { // cannot disable already selected tab
- this.$lis.eq(index).addClass(o.disabledClass);
-
- o.disabled.push(index);
- o.disabled.sort();
-
- // callback
- this._trigger('disable', null, this.ui(this.$tabs[index], this.$panels[index]));
- }
- },
- select: function(index) {
- if (typeof index == 'string')
- index = this.$tabs.index( this.$tabs.filter('[href$=' + index + ']')[0] );
- this.$tabs.eq(index).trigger(this.options.event);
- },
- load: function(index, callback) { // callback is for internal usage only
-
- var self = this, o = this.options, $a = this.$tabs.eq(index), a = $a[0],
- bypassCache = callback == undefined || callback === false, url = $a.data('load.tabs');
-
- callback = callback || function() {};
-
- // no remote or from cache - just finish with callback
- if (!url || !bypassCache && $.data(a, 'cache.tabs')) {
- callback();
- return;
- }
-
- // load remote from here on
-
- var inner = function(parent) {
- var $parent = $(parent), $inner = $parent.find('*:last');
- return $inner.length && $inner.is(':not(img)') && $inner || $parent;
- };
- var cleanup = function() {
- self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass)
- .each(function() {
- if (o.spinner)
- inner(this).parent().html(inner(this).data('label.tabs'));
- });
- self.xhr = null;
- };
-
- if (o.spinner) {
- var label = inner(a).html();
- inner(a).wrapInner('<em></em>')
- .find('em').data('label.tabs', label).html(o.spinner);
- }
-
- var ajaxOptions = $.extend({}, o.ajaxOptions, {
- url: url,
- success: function(r, s) {
- $(a.hash).html(r);
- cleanup();
-
- if (o.cache)
- $.data(a, 'cache.tabs', true); // if loaded once do not load them again
-
- // callbacks
- self._trigger('load', null, self.ui(self.$tabs[index], self.$panels[index]));
- o.ajaxOptions.success && o.ajaxOptions.success(r, s);
-
- // This callback is required because the switch has to take
- // place after loading has completed. Call last in order to
- // fire load before show callback...
- callback();
- }
- });
- if (this.xhr) {
- // terminate pending requests from other tabs and restore tab label
- this.xhr.abort();
- cleanup();
- }
- $a.addClass(o.loadingClass);
- setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
- self.xhr = $.ajax(ajaxOptions);
- }, 0);
-
- },
- url: function(index, url) {
- this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url);
- },
- destroy: function() {
- var o = this.options;
- this.element.unbind('.tabs')
- .removeClass(o.navClass).removeData('tabs');
- this.$tabs.each(function() {
- var href = $.data(this, 'href.tabs');
- if (href)
- this.href = href;
- var $this = $(this).unbind('.tabs');
- $.each(['href', 'load', 'cache'], function(i, prefix) {
- $this.removeData(prefix + '.tabs');
- });
- });
- this.$lis.add(this.$panels).each(function() {
- if ($.data(this, 'destroy.tabs'))
- $(this).remove();
- else
- $(this).removeClass([o.selectedClass, o.unselectClass,
- o.disabledClass, o.panelClass, o.hideClass].join(' '));
- });
- }
-});
-
-$.ui.tabs.defaults = {
- // basic setup
- unselect: false,
- event: 'click',
- disabled: [],
- cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
- // TODO history: false,
-
- // Ajax
- spinner: 'Loading…',
- cache: false,
- idPrefix: 'ui-tabs-',
- ajaxOptions: {},
-
- // animations
- fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
-
- // templates
- tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>',
- panelTemplate: '<div></div>',
-
- // CSS classes
- navClass: 'ui-tabs-nav',
- selectedClass: 'ui-tabs-selected',
- unselectClass: 'ui-tabs-unselect',
- disabledClass: 'ui-tabs-disabled',
- panelClass: 'ui-tabs-panel',
- hideClass: 'ui-tabs-hide',
- loadingClass: 'ui-tabs-loading'
-};
-
-$.ui.tabs.getter = "length";
-
-/*
- * Tabs Extensions
- */
-
-/*
- * Rotate
- */
-$.extend($.ui.tabs.prototype, {
- rotation: null,
- rotate: function(ms, continuing) {
-
- continuing = continuing || false;
-
- var self = this, t = this.options.selected;
-
- function start() {
- self.rotation = setInterval(function() {
- t = ++t < self.$tabs.length ? t : 0;
- self.select(t);
- }, ms);
- }
-
- function stop(e) {
- if (!e || e.clientX) { // only in case of a true click
- clearInterval(self.rotation);
- }
- }
-
- // start interval
- if (ms) {
- start();
- if (!continuing)
- this.$tabs.bind(this.options.event, stop);
- else
- this.$tabs.bind(this.options.event, function() {
- stop();
- t = self.options.selected;
- start();
- });
- }
- // stop interval
- else {
- stop();
- this.$tabs.unbind(this.options.event, stop);
- }
- }
-});
-
-})(jQuery);
--- a/web/test/unittest_form.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_form.py Thu Jul 02 10:35:03 2009 +0200
@@ -91,7 +91,7 @@
e.req = self.req
geid = self.execute('CWGroup X WHERE X name "users"')[0][0]
self.req.form['__linkto'] = 'in_group:%s:subject' % geid
- form = self.vreg.select_object('forms', 'edition', self.req, None, entity=e)
+ form = self.vreg.select('forms', 'edition', self.req, entity=e)
form.content_type = 'text/html'
pageinfo = self._check_html(form.form_render(), form, template=None)
inputs = pageinfo.find_tag('select', False)
--- a/web/test/unittest_magicsearch.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_magicsearch.py Thu Jul 02 10:35:03 2009 +0200
@@ -44,7 +44,7 @@
super(QueryTranslatorTC, self).setUp()
self.req = self.env.create_request()
self.vreg.config.translations = {'en': _translate}
- proc = self.vreg.select_component('magicsearch', self.req)
+ proc = self.vreg.select('components', 'magicsearch', self.req)
self.proc = [p for p in proc.processors if isinstance(p, QueryTranslator)][0]
def test_basic_translations(self):
@@ -69,7 +69,7 @@
super(QSPreProcessorTC, self).setUp()
self.vreg.config.translations = {'en': _translate}
self.req = self.request()
- proc = self.vreg.select_component('magicsearch', self.req)
+ proc = self.vreg.select('components', 'magicsearch', self.req)
self.proc = [p for p in proc.processors if isinstance(p, QSPreProcessor)][0]
self.proc.req = self.req
@@ -191,7 +191,7 @@
super(ProcessorChainTC, self).setUp()
self.vreg.config.translations = {'en': _translate}
self.req = self.request()
- self.proc = self.vreg.select_component('magicsearch', self.req)
+ self.proc = self.vreg.select('components', 'magicsearch', self.req)
def test_main_preprocessor_chain(self):
"""tests QUERY_PROCESSOR"""
--- a/web/test/unittest_views_actions.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_views_actions.py Thu Jul 02 10:35:03 2009 +0200
@@ -13,19 +13,19 @@
def test_view_action(self):
req = self.request(__message='bla bla bla', vid='rss', rql='CWUser X')
rset = self.execute('CWUser X')
- vaction = [action for action in self.vreg.possible_vobjects('actions', req, rset)
+ vaction = [action for action in self.vreg.possible_vobjects('actions', req, rset=rset)
if action.id == 'view'][0]
self.assertEquals(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X')
def test_sendmail_action(self):
req = self.request()
rset = self.execute('Any X WHERE X login "admin"', req=req)
- self.failUnless([action for action in self.vreg.possible_vobjects('actions', req, rset)
+ self.failUnless([action for action in self.vreg.possible_vobjects('actions', req, rset=rset)
if action.id == 'sendemail'])
self.login('anon')
req = self.request()
rset = self.execute('Any X WHERE X login "anon"', req=req)
- self.failIf([action for action in self.vreg.possible_vobjects('actions', req, rset)
+ self.failIf([action for action in self.vreg.possible_vobjects('actions', req, rset=rset)
if action.id == 'sendemail'])
if __name__ == '__main__':
--- a/web/test/unittest_views_basecontrollers.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_views_basecontrollers.py Thu Jul 02 10:35:03 2009 +0200
@@ -499,7 +499,7 @@
# updated (which is what happened before this test)
req = self.request()
req.form['url'] = 'http://intranet.logilab.fr/'
- controller = self.env.app.select_controller('embed', req)
+ controller = self.vreg.select('controllers', 'embed', req)
result = controller.publish(rset=None)
@@ -507,7 +507,7 @@
def test_usable_by_guets(self):
req = self.request()
- self.env.app.select_controller('reportbug', req)
+ self.vreg.select('controllers', 'reportbug', req)
class SendMailControllerTC(EnvBasedTC):
@@ -523,7 +523,7 @@
def ctrl(self, req=None):
req = req or self.request(url='http://whatever.fr/')
- return self.env.app.select_controller('json', req)
+ return self.vreg.select('controllers', 'json', req)
def setup_database(self):
self.pytag = self.add_entity('Tag', name=u'python')
--- a/web/test/unittest_views_baseforms.py Thu Jul 02 10:30:44 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,250 +0,0 @@
-"""cubicweb.web.views.baseforms unit tests
-
-:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
-"""
-
-from StringIO import StringIO
-from datetime import date
-import re
-
-
-from logilab.common.testlib import unittest_main
-from logilab.common.decorators import clear_cache
-from cubicweb.devtools.apptest import EnvBasedTC
-from cubicweb.entities import AnyEntity
-from cubicweb.web import widgets
-
-orig_now = widgets.datetime.now
-
-def setup_module(options):
- def _today():
- return date(0000, 1, 1)
- widgets.datetime.now = _today
-
-def teardown_module(options, results):
- widgets.datetime.now = orig_now
-
-
-def cleanup_text(text):
- return re.sub('\d\d:\d\d', 'hh:mm', re.sub('\d+/\d\d/\d\d', 'YYYY/MM/DD', '\n'.join(l.strip() for l in text.splitlines() if l.strip())))
-
-
-
-class EditionFormTC(EnvBasedTC):
-
- def setup_database(self):
- self.create_user('joe')
-
- def _build_creation_form(self, etype):
- req = self.request()
- req.next_tabindex()
- req.next_tabindex()
- req.del_page_data()
- req.form['etype'] = etype
- view = self.vreg.select_view('creation', req, None)
- entity = self.vreg.etype_class(etype)(req, None, None)
- buffer = StringIO()
- view.w = buffer.write
- view.edit_form(entity, {})
- return buffer.getvalue()
-
- def _test_view_for(self, etype, expected):
- self.assertTextEquals(expected, cleanup_text(self._build_creation_form(etype)))
-
- def test_base(self):
- self._test_view_for('CWGroup', '''\
-<form id="entityForm" class="entityForm" cubicweb:target="eformframe"
-method="post" onsubmit="return freezeFormButtons('entityForm')" enctype="application/x-www-form-urlencoded" action="http://testing.fr/cubicweb/validateform">
-<div class="formTitle"><span>egroup (creation)</span></div>
-<div id="progress">validating...</div>
-<div class="iformTitle"><span>main informations</span></div>
-<div class="formBody"><fieldset>
-<input type="hidden" name="eid" value="A" />
-<input type="hidden" name="__type:A" value="CWGroup" />
-<input type="hidden" name="__maineid" value="A" />
-<input id="errorurl" type="hidden" name="__errorurl" value="http://testing.fr/cubicweb/view?rql=Blop&vid=blop" />
-<input type="hidden" name="__form_id" value="edition" />
-<input type="hidden" name="__message" value="element created" />
-<table id="entityFormA" class="attributeForm" style="width:100%;">
-<tr>
-<th class="labelCol"><label class="required" for="name:A">name</label></th>
-<td style="width:100%;">
-<input type="hidden" name="edits-name:A" value="__cubicweb_internal_field__"/>
-<input type="text" name="name:A" value="" accesskey="n" id="name:A" maxlength="64" size="40" tabindex="2"/>
-<br/>
-</td>
-</tr>
-</table>
-</fieldset>
-</div>
-<table width="100%">
-<tbody>
-<tr><td align="center">
-<input class="validateButton" type="submit" name="defaultsubmit" value="Button_ok" tabindex="3"/>
-</td><td style="align: right; width: 50%;">
-<input class="validateButton" type="button" onclick="postForm('__action_apply', 'Button_apply', 'entityForm')" value="Button_apply" tabindex="4"/>
-<input class="validateButton" type="button" onclick="postForm('__action_cancel', 'Button_cancel', 'entityForm')" value="Button_cancel" tabindex="5"/>
-</td></tr>
-</tbody>
-</table>
-</form>''')
-
- def test_with_inline_view(self):
- activated = self.execute('Any X WHERE X is State, X name "activated"')[0][0]
- self._test_view_for('CWUser', '''<form id="entityForm" class="entityForm" cubicweb:target="eformframe"
-method="post" onsubmit="return freezeFormButtons('entityForm')" enctype="application/x-www-form-urlencoded" action="http://testing.fr/cubicweb/validateform">
-<div class="formTitle"><span>euser (creation)</span></div>
-<div id="progress">validating...</div>
-<div class="iformTitle"><span>main informations</span></div>
-<div class="formBody"><fieldset>
-<input type="hidden" name="eid" value="A" />
-<input type="hidden" name="__type:A" value="CWUser" />
-<input type="hidden" name="__maineid" value="A" />
-<input id="errorurl" type="hidden" name="__errorurl" value="http://testing.fr/cubicweb/view?rql=Blop&vid=blop" />
-<input type="hidden" name="__form_id" value="edition" />
-<input type="hidden" name="__message" value="element created" />
-<table id="entityFormA" class="attributeForm" style="width:100%%;">
-<tr>
-<th class="labelCol"><label class="required" for="login:A">login</label></th>
-<td style="width:100%%;">
-<input type="hidden" name="edits-login:A" value="__cubicweb_internal_field__"/>
-<input type="text" name="login:A" value="" accesskey="l" id="login:A" maxlength="64" size="40" tabindex="2"/>
-<br/> <span class="helper">unique identifier used to connect to the application</span>
-</td>
-</tr>
-<tr>
-<th class="labelCol"><label class="required" for="upassword:A">upassword</label></th>
-<td style="width:100%%;">
-<input type="hidden" name="edits-upassword:A" value="__cubicweb_internal_field__"/>
-<input type="password" name="upassword:A" value="" accesskey="u" id="upassword:A" tabindex="3"/><br/>
-<input type="password" name="upassword-confirm:A" id="upassword-confirm:A" tabindex="4"/> <span class="emphasis">(confirm password)</span>
-<br/>
-</td>
-</tr>
-<tr>
-<th class="labelCol"><label for="firstname:A">firstname</label></th>
-<td style="width:100%%;">
-<input type="hidden" name="edits-firstname:A" value="__cubicweb_internal_field__"/>
-<input type="text" name="firstname:A" value="" accesskey="f" id="firstname:A" maxlength="64" size="40" tabindex="5"/>
-<br/>
-</td>
-</tr>
-<tr>
-<th class="labelCol"><label for="surname:A">surname</label></th>
-<td style="width:100%%;">
-<input type="hidden" name="edits-surname:A" value="__cubicweb_internal_field__"/>
-<input type="text" name="surname:A" value="" accesskey="s" id="surname:A" maxlength="64" size="40" tabindex="6"/>
-<br/>
-</td>
-</tr>
-<tr>
-<th class="labelCol"><label class="required" for="in_group:A">in_group</label></th>
-<td style="width:100%%;">
-<input type="hidden" name="edits-in_group:A" value="__cubicweb_internal_field__"/>
-<select name="in_group:A" id="in_group:A" multiple="multiple" size="5" tabindex="7">
-<option value="3" >guests</option>
-<option value="1" >managers</option>
-<option value="2" >users</option>
-</select>
-<br/> <span class="helper">groups grant permissions to the user</span>
-</td>
-</tr>
-<tr>
-<th class="labelCol"><label class="required" for="in_state:A">in_state</label></th>
-<td style="width:100%%;">
-<input type="hidden" name="edits-in_state:A" value="__cubicweb_internal_field__"/>
-<select name="in_state:A" id="in_state:A" tabindex="8">
-<option value="%(activated)s" >activated</option>
-</select>
-<br/> <span class="helper">account state</span>
-</td>
-</tr>
-</table>
-<div id="inlineuse_emailslot">
-<div class="inlinedform" id="addNewEmailAddressuse_emailsubject:A" cubicweb:limit="true">
-<a class="addEntity" id="adduse_email:Alink" href="javascript: addInlineCreationForm('A', 'CWUser', 'EmailAddress', 'use_email', 'subject')" >+ add a EmailAddress.</a>
-</div>
-<div class="trame_grise"> </div>
-</div>
-</fieldset>
-</div>
-<table width="100%%">
-<tbody>
-<tr><td align="center">
-<input class="validateButton" type="submit" name="defaultsubmit" value="Button_ok" tabindex="9"/>
-</td><td style="align: right; width: 50%%;">
-<input class="validateButton" type="button" onclick="postForm('__action_apply', 'Button_apply', 'entityForm')" value="Button_apply" tabindex="10"/>
-<input class="validateButton" type="button" onclick="postForm('__action_cancel', 'Button_cancel', 'entityForm')" value="Button_cancel" tabindex="11"/>
-</td></tr>
-</tbody>
-</table>
-</form>''' % {'activated' : activated})
-
- def test_redirection_after_creation(self):
- req = self.request()
- req.form['etype'] = 'CWUser'
- view = self.vreg.select_view('creation', req, None)
- self.assertEquals(view.redirect_url(), 'http://testing.fr/cubicweb/euser')
- req.form['__redirectrql'] = 'Any X WHERE X eid 3012'
- req.form['__redirectvid'] = 'avid'
- self.assertEquals(view.redirect_url(), 'http://testing.fr/cubicweb/view?rql=Any%20X%20WHERE%20X%20eid%203012&vid=avid')
-
-
- def test_need_multipart(self):
- req = self.request()
- class Salesterm(AnyEntity):
- id = 'Salesterm'
- __rtags__ = {'described_by_test' : 'inlineview'}
- vreg = self.vreg
- vreg.register_vobject_class(Salesterm)
- req.form['etype'] = 'Salesterm'
- entity = vreg.etype_class('Salesterm')(req, None, None)
- view = vreg.select_view('creation', req, None)
- self.failUnless(view.need_multipart(entity))
-
-
-
- def test_nonregr_check_add_permission_on_relation(self):
- from cubes.blog.entities import BlogEntry
- class BlogEntryPlus(BlogEntry):
- __rtags__ = {'checked_by': 'primary'}
- self.vreg.register_vobject_class(BlogEntryPlus)
- clear_cache(self.vreg, 'etype_class')
- # an admin should be able to edit the checked_by relation
- html = self._build_creation_form('BlogEntry')
- self.failUnless('name="edits-checked_by:A"' in html)
- # a regular user should not be able to see the relation
- self.login('joe')
- html = self._build_creation_form('BlogEntry')
- self.failIf('name="edits-checked_by:A"' in html)
-
-from cubicweb.devtools.testlib import WebTest
-from cubicweb.devtools.htmlparser import DTDValidator
-
-class CopyWebTest(WebTest):
-
- def setup_database(self):
- p = self.create_user("Doe")
- # do not try to skip 'primary_email' for this test
- e = self.add_entity('EmailAddress', address=u'doe@doe.com')
- self.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
- {'p' : p.eid, 'e' : e.eid})
-
-
- def test_cloned_elements_in_copy_form(self):
- rset = self.execute('CWUser P WHERE P login "Doe"')
- output = self.view('copy', rset)
- clones = [attrs for _, attrs in output.input_tags
- if attrs.get('name', '').startswith('__cloned_eid')]
- # the only cloned entity should be the original person
- self.assertEquals(len(clones), 1)
- attrs = clones[0]
- self.assertEquals(attrs['name'], '__cloned_eid:A')
- self.assertEquals(int(attrs['value']), rset[0][0])
-
-
-if __name__ == '__main__':
- unittest_main()
--- a/web/test/unittest_views_baseviews.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_views_baseviews.py Thu Jul 02 10:35:03 2009 +0200
@@ -86,7 +86,7 @@
rset = self.execute('Any X, D, CD, NOW - CD WHERE X is State, X description D, X creation_date CD, X eid %(x)s',
{'x': e.eid}, 'x')
req = self.request()
- view = self.vreg.select_view('table', req, rset)
+ view = self.vreg.select('views', 'table', req, rset)
return e, rset, view
def test_headers(self):
--- a/web/test/unittest_views_editforms.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_views_editforms.py Thu Jul 02 10:35:03 2009 +0200
@@ -18,8 +18,8 @@
def test_custom_widget(self):
AEF.rfields_kwargs.tag_subject_of(('CWUser', 'login', '*'),
{'widget':AutoCompletionWidget})
- form = self.vreg.select_object('forms', 'edition', self.request(), None,
- entity=self.user())
+ form = self.vreg.select('forms', 'edition', self.request(),
+ entity=self.user())
field = form.field_by_name('login')
self.assertIsInstance(field.widget, AutoCompletionWidget)
AEF.rfields_kwargs.del_rtag('CWUser', 'login', '*', 'subject')
@@ -114,11 +114,11 @@
def test_edition_form(self):
rset = self.execute('CWUser X LIMIT 1')
- form = self.vreg.select_object('forms', 'edition', rset.req, rset,
- row=0, col=0)
+ form = self.vreg.select('forms', 'edition', rset.req, rset=rset,
+ row=0, col=0)
# should be also selectable by specifying entity
- self.vreg.select_object('forms', 'edition', self.request(), None,
- entity=rset.get_entity(0, 0))
+ self.vreg.select('forms', 'edition', rset.req,
+ entity=rset.get_entity(0, 0))
self.failIf(any(f for f in form.fields if f is None))
--- a/web/test/unittest_views_navigation.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_views_navigation.py Thu Jul 02 10:35:03 2009 +0200
@@ -19,31 +19,31 @@
def test_navigation_selection(self):
rset = self.execute('Any X,N WHERE X name N')
req = self.request()
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
self.assertIsInstance(navcomp, PageNavigation)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
self.assertIsInstance(navcomp, PageNavigation)
req.set_search_state('normal')
rset = self.execute('Any X,N ORDERBY N WHERE X name N')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
req.set_search_state('normal')
rset = self.execute('Any X,N LIMIT 10 WHERE X name N')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select_object('components', 'navigation', req, rset=rset)
self.assertEquals(navcomp, None)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select_object('components', 'navigation', req, rset=rset)
self.assertEquals(navcomp, None)
req.set_search_state('normal')
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', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
@@ -51,22 +51,22 @@
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)
+ navcomp = self.vreg.select('components', 'navigation', rset.req, rset=rset)
html = navcomp.render()
rset = self.execute('Any RDEF ORDERBY RT WHERE RDEF relation_type RT')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
html = navcomp.render()
rset = self.execute('Any RDEF ORDERBY RDEF WHERE RDEF relation_type RT')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
html = navcomp.render()
rset = self.execute('CWAttribute RDEF ORDERBY RDEF')
- navcomp = self.vreg.select_component('navigation', req, rset)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
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)
+ navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
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)
+ navcomp = self.vreg.select('components', 'navigation', rset.req, rset=rset)
html = navcomp.render()
@@ -77,12 +77,12 @@
view = mock_object(is_primary=lambda x: True)
rset = self.execute('CWUser X LIMIT 1')
req = self.request()
- objs = self.vreg.possible_vobjects('contentnavigation', req, rset,
+ objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset,
view=view, context='navtop')
# breadcrumbs should be in headers by default
clsids = set(obj.id for obj in objs)
self.failUnless('breadcrumbs' in clsids)
- objs = self.vreg.possible_vobjects('contentnavigation', req, rset,
+ objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset,
view=view, context='navbottom')
# breadcrumbs should _NOT_ be in footers by default
clsids = set(obj.id for obj in objs)
@@ -91,12 +91,12 @@
'P value "navbottom"')
# breadcrumbs should now be in footers
req.cnx.commit()
- objs = self.vreg.possible_vobjects('contentnavigation', req, rset,
+ objs = self.vreg.possible_vobjects('contentnavigation', req, rset=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,
+ objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset,
view=view, context='navtop')
clsids = [obj.id for obj in objs]
--- a/web/test/unittest_views_pyviews.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_views_pyviews.py Thu Jul 02 10:35:03 2009 +0200
@@ -4,9 +4,9 @@
class PyViewsTC(EnvBasedTC):
def test_pyvaltable(self):
- content = self.vreg.view('pyvaltable', self.request(),
- pyvalue=[[1, 'a'], [2, 'b']],
- headers=['num', 'char'])
+ content = self.vreg.render('pyvaltable', self.request(),
+ pyvalue=[[1, 'a'], [2, 'b']],
+ headers=['num', 'char'])
self.assertEquals(content.strip(), '''<table class="listing">
<tr><th>num</th><th>char</th></tr>
<tr><td>1</td><td>a</td></tr>
@@ -14,8 +14,8 @@
</table>''')
def test_pyvallist(self):
- content = self.vreg.view('pyvallist', self.request(),
- pyvalue=[1, 'a'])
+ content = self.vreg.render('pyvallist', self.request(),
+ pyvalue=[1, 'a'])
self.assertEquals(content.strip(), '''<ul>
<li>1</li>
<li>a</li>
--- a/web/test/unittest_viewselector.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/test/unittest_viewselector.py Thu Jul 02 10:35:03 2009 +0200
@@ -234,7 +234,7 @@
req = self.request()
# creation form
req.form['etype'] = 'CWGroup'
- self.assertIsInstance(self.vreg.select_view('creation', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'creation', req, rset=rset),
editforms.CreationFormView)
del req.form['etype']
# custom creation form
@@ -243,94 +243,94 @@
self.vreg._loadedmods[__name__] = {}
self.vreg.register_vobject_class(CWUserCreationForm)
req.form['etype'] = 'CWUser'
- self.assertIsInstance(self.vreg.select_view('creation', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'creation', req, rset=rset),
CWUserCreationForm)
def test_select_view(self):
# no entity
rset = None
req = self.request()
- self.assertIsInstance(self.vreg.select_view('index', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'index', req, rset=rset),
startup.IndexView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'primary', req, rset)
+ self.vreg.select, 'views', 'primary', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'table', req, rset)
+ self.vreg.select, 'views', 'table', req, rset=rset)
# no entity
rset, req = self.env.get_rset_and_req('Any X WHERE X eid 999999')
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'index', req, rset)
+ self.vreg.select, 'views', 'index', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'creation', req, rset)
+ self.vreg.select, 'views', 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'primary', req, rset)
+ self.vreg.select, 'views', 'primary', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'table', req, rset)
+ self.vreg.select, 'views', 'table', req, rset=rset)
# one entity
rset, req = self.env.get_rset_and_req('CWGroup X WHERE X name "managers"')
- self.assertIsInstance(self.vreg.select_view('primary', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
primary.PrimaryView)
- self.assertIsInstance(self.vreg.select_view('list', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset),
baseviews.ListView)
- self.assertIsInstance(self.vreg.select_view('edition', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'edition', req, rset=rset),
editforms.EditionFormView)
- self.assertIsInstance(self.vreg.select_view('table', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'creation', req, rset)
+ self.vreg.select, 'views', 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'index', req, rset)
+ self.vreg.select, 'views', 'index', req, rset=rset)
# list of entities of the same type
rset, req = self.env.get_rset_and_req('CWGroup X')
- self.assertIsInstance(self.vreg.select_view('primary', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
primary.PrimaryView)
- self.assertIsInstance(self.vreg.select_view('list', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset),
baseviews.ListView)
- self.assertIsInstance(self.vreg.select_view('table', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'creation', req, rset)
+ self.vreg.select, 'views', 'creation', req, rset=rset)
# list of entities of different types
rset, req = self.env.get_rset_and_req('Any X')
- self.assertIsInstance(self.vreg.select_view('primary', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
primary.PrimaryView)
- self.assertIsInstance(self.vreg.select_view('list', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset),
baseviews.ListView)
- self.assertIsInstance(self.vreg.select_view('table', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'creation', req, rset)
+ self.vreg.select, 'views', 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'index', req, rset)
+ self.vreg.select, 'views', 'index', req, rset=rset)
# whatever
rset, req = self.env.get_rset_and_req('Any N, X WHERE X in_group Y, Y name N')
- self.assertIsInstance(self.vreg.select_view('table', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'index', req, rset)
+ self.vreg.select, 'views', 'index', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'creation', req, rset)
+ self.vreg.select, 'views', 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'primary', req, rset)
+ self.vreg.select, 'views', 'primary', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'list', req, rset)
+ self.vreg.select, 'views', 'list', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'edition', req, rset)
+ self.vreg.select, 'views', 'edition', req, rset=rset)
# mixed query
rset, req = self.env.get_rset_and_req('Any U,G WHERE U is CWUser, G is CWGroup')
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'edition', req, rset)
+ self.vreg.select, 'views', 'edition', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select_view, 'creation', req, rset)
- self.assertIsInstance(self.vreg.select_view('table', req, rset),
+ self.vreg.select, 'views', 'creation', req, rset=rset)
+ self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
tableview.TableView)
def test_interface_selector(self):
image = self.add_entity('Image', name=u'bim.png', data=Binary('bim'))
# image primary view priority
rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"')
- self.assertIsInstance(self.vreg.select_view('primary', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
idownloadable.IDownloadablePrimaryView)
@@ -338,12 +338,12 @@
image = self.add_entity('Image', name=u'bim.png', data=Binary('bim'))
# image primary view priority
rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"')
- self.assertIsInstance(self.vreg.select_view('image', req, rset),
+ self.assertIsInstance(self.vreg.select('views', 'image', req, rset=rset),
idownloadable.ImageView)
fileobj = self.add_entity('File', name=u'bim.txt', data=Binary('bim'))
# image primary view priority
rset, req = self.env.get_rset_and_req('File X WHERE X name "bim.txt"')
- self.assertRaises(NoSelectableObject, self.vreg.select_view, 'image', req, rset)
+ self.assertRaises(NoSelectableObject, self.vreg.select, 'views', 'image', req, rset=rset)
@@ -354,7 +354,7 @@
else:
rset, req = self.env.get_rset_and_req(rql)
try:
- self.vreg.render('views', vid, req, rset=rset, **args)
+ self.vreg.render(vid, req, rset=rset, **args)
except:
print vid, rset, args
raise
--- a/web/uicfg.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/uicfg.py Thu Jul 02 10:35:03 2009 +0200
@@ -169,7 +169,11 @@
# * 'schema'
# * 'subobject' (not displayed by default)
-indexview_etype_section = {'EmailAddress': 'subobject'}
+indexview_etype_section = {'EmailAddress': 'subobject',
+ 'CWUser': 'system',
+ 'CWGroup': 'system',
+ 'CWPermission': 'system',
+ }
# autoform.AutomaticEntityForm configuration ##################################
--- a/web/views/basecontrollers.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/basecontrollers.py Thu Jul 02 10:35:03 2009 +0200
@@ -128,12 +128,12 @@
req.set_message(req._("error while handling __method: %s") % req._(ex))
vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema)
try:
- view = self.vreg.select_view(vid, req, rset)
+ view = self.vreg.select('views', vid, req, rset=rset)
except ObjectNotFound:
self.warning("the view %s could not be found", vid)
req.set_message(req._("The view %s could not be found") % vid)
vid = vid_from_rset(req, rset, self.schema)
- view = self.vreg.select_view(vid, req, rset)
+ view = self.vreg.select('views', vid, req, rset=rset)
except NoSelectableObject:
if rset:
req.set_message(req._("The view %s can not be applied to this query") % vid)
@@ -141,7 +141,7 @@
req.set_message(req._("You have no access to this view or it's not applyable to current data"))
self.warning("the view %s can not be applied to this query", vid)
vid = vid_from_rset(req, rset, self.schema)
- view = self.vreg.select_view(vid, req, rset)
+ view = self.vreg.select('views', vid, req, rset=rset)
return view, rset
def add_to_breadcrumbs(self, view):
@@ -184,8 +184,8 @@
def publish(self, rset=None):
vreg = self.vreg
try:
- ctrl = vreg.select(vreg.registry_objects('controllers', 'edit'),
- req=self.req, appli=self.appli)
+ ctrl = vreg.select('controllers', 'edit', self.req,
+ appli=self.appli)
except NoSelectableObject:
status, args = (False, {None: self.req._('not authorized')})
else:
@@ -256,6 +256,8 @@
except RemoteCallFailed:
raise
except Exception, ex:
+ import traceback
+ traceback.print_exc()
self.exception('an exception occured while calling js_%s(%s): %s',
fname, args, ex)
raise RemoteCallFailed(repr(ex))
@@ -308,10 +310,10 @@
rset = None
vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema)
try:
- view = self.vreg.select_view(vid, req, rset)
+ view = self.vreg.select('views', vid, req, rset=rset)
except NoSelectableObject:
vid = req.form.get('fallbackvid', 'noresult')
- view = self.vreg.select_view(vid, req, rset)
+ view = self.vreg.select('views', vid, req, rset=rset)
divid = req.form.get('divid', 'pageContent')
# we need to call pagination before with the stream set
stream = view.set_stream()
@@ -341,8 +343,7 @@
entity = self.vreg.etype_class('CWProperty')(self.req, None, None)
entity.eid = varname
entity['pkey'] = propkey
- form = self.vreg.select_object('forms', 'edition', self.req, None,
- entity=entity)
+ form = self.vreg.select('forms', 'edition', self.req, entity=entity)
form.form_build_context()
vfield = form.field_by_name('value')
renderer = FormRenderer(self.req)
@@ -355,7 +356,7 @@
rset = self._exec(rql)
else:
rset = None
- comp = self.vreg.select_object(registry, compid, self.req, rset)
+ comp = self.vreg.select(registry, compid, self.req, rset=rset)
if extraargs is None:
extraargs = {}
else: # we receive unicode keys which is not supported by the **syntax
@@ -367,9 +368,8 @@
@check_pageid
@xhtmlize
def js_inline_creation_form(self, peid, ttype, rtype, role):
- view = self.vreg.select_view('inline-creation', self.req, None,
- etype=ttype, peid=peid, rtype=rtype,
- role=role)
+ view = self.vreg.select('views', 'inline-creation', self.req,
+ etype=ttype, peid=peid, rtype=rtype, role=role)
return view.render(etype=ttype, peid=peid, rtype=rtype, role=role)
@jsonize
@@ -382,8 +382,7 @@
self.req.form = self._rebuild_posted_form(names, values, action)
vreg = self.vreg
try:
- ctrl = vreg.select(vreg.registry_objects('controllers', 'edit'),
- req=self.req)
+ ctrl = vreg.select('controllers', 'edit', self.req)
except NoSelectableObject:
return (False, {None: self.req._('not authorized')})
try:
--- a/web/views/basetemplates.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/basetemplates.py Thu Jul 02 10:35:03 2009 +0200
@@ -112,9 +112,9 @@
if vtitle:
w(u'<h1 class="vtitle">%s</h1>\n' % html_escape(vtitle))
# display entity type restriction component
- etypefilter = self.vreg.select_component('etypenavigation',
- self.req, self.rset)
- if etypefilter and etypefilter.propval('visible'):
+ etypefilter = self.vreg.select_vobject('components', 'etypenavigation',
+ self.req, rset=self.rset)
+ if etypefilter:
etypefilter.render(w=w)
self.nav_html = UStringIO()
if view and view.need_navigation:
@@ -152,10 +152,12 @@
w(u'<div id="page"><table width="100%" border="0" id="mainLayout"><tr>\n')
self.nav_column(view, 'left')
w(u'<td id="contentcol">\n')
- rqlcomp = self.vreg.select_component('rqlinput', self.req, self.rset)
+ rqlcomp = self.vreg.select_object('components', 'rqlinput', self.req,
+ rset=self.rset)
if rqlcomp:
rqlcomp.render(w=self.w, view=view)
- msgcomp = self.vreg.select_component('applmessages', self.req, self.rset)
+ msgcomp = self.vreg.select_object('components', 'applmessages',
+ self.req, rset=self.rset)
if msgcomp:
msgcomp.render(w=self.w)
self.content_header(view)
@@ -169,7 +171,7 @@
self.w(u'</body>')
def nav_column(self, view, context):
- boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset,
+ boxes = list(self.vreg.possible_vobjects('boxes', self.req, rset=self.rset,
view=view, context=context))
if boxes:
self.w(u'<td class="navcol"><div class="navboxes">\n')
@@ -196,7 +198,7 @@
"""display an unexpected error"""
self.set_request_content_type()
self.req.reset_headers()
- view = self.vreg.select_view('error', self.req, self.rset)
+ view = self.vreg.select('views', 'error', self.req, rset=self.rset)
self.template_header(self.content_type, view, self.req._('an error occured'),
[NOINDEX, NOFOLLOW])
view.render(w=self.w)
@@ -238,7 +240,7 @@
w(u'<table width="100%" height="100%" border="0"><tr>\n')
w(u'<td class="navcol">\n')
self.topleft_header()
- boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset,
+ boxes = list(self.vreg.possible_vobjects('boxes', self.req, rset=self.rset,
view=view, context='left'))
if boxes:
w(u'<div class="navboxes">\n')
@@ -253,11 +255,14 @@
w(u'<h1 class="vtitle">%s</h1>' % html_escape(vtitle))
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).render(w=self.w)
- self.w(u'</td>\n')
- self.w(u'</tr></table>\n')
+ logo = self.vreg.select_vobject('components', 'logo', self.req,
+ rset=self.rset)
+ if logo:
+ self.w(u'<table id="header"><tr>\n')
+ self.w(u'<td>')
+ logo.render(w=self.w)
+ self.w(u'</td>\n')
+ self.w(u'</tr></table>\n')
# page parts templates ########################################################
@@ -292,11 +297,11 @@
self.req.add_js(jscript, localfile=False)
def alternates(self):
- urlgetter = self.vreg.select_component('rss_feed_url', self.req, self.rset)
+ urlgetter = self.vreg.select_object('components', 'rss_feed_url',
+ self.req, rset=self.rset)
if urlgetter is not None:
- url = urlgetter.feed_url()
self.whead(u'<link rel="alternate" type="application/rss+xml" title="RSS feed" href="%s"/>\n'
- % html_escape(url))
+ % html_escape(urlgetter.feed_url()))
def pageid(self):
req = self.req
@@ -322,24 +327,29 @@
"""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).render(w=self.w)
+ logo = self.vreg.select_vobject('components', 'logo',
+ self.req, rset=self.rset)
+ if logo:
+ logo.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.render(w=self.w)
- comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
- if comp and comp.propval('visible'):
- comp.render(w=self.w, view=view)
+ for cid in ('appliname', 'breadcrumbs'):
+ comp = self.vreg.select_vobject('components', cid,
+ self.req, rset=self.rset)
+ if comp:
+ comp.render(w=self.w)
self.w(u'</td>')
# logged user and help
self.w(u'<td>\n')
- comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
- comp.render(w=self.w)
+ comp = self.vreg.select_vobject('components', 'loggeduserlink',
+ self.req, rset=self.rset)
+ if comp:
+ 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 = self.vreg.select_vobject('components', 'help',
+ self.req, rset=self.rset)
+ if helpcomp:
helpcomp.render(w=self.w)
self.w(u'</td>')
# lastcolumn
@@ -394,7 +404,7 @@
def call(self, view, **kwargs):
"""by default, display informal messages in content header"""
components = self.vreg.possible_vobjects('contentnavigation',
- self.req, self.rset,
+ self.req, rset=self.rset,
view=view, context='navtop')
if components:
self.w(u'<div id="contentheader">')
@@ -411,7 +421,7 @@
def call(self, view, **kwargs):
components = self.vreg.possible_vobjects('contentnavigation',
- self.req, self.rset,
+ self.req, rset=self.rset,
view=view, context='navbottom')
if components:
self.w(u'<div id="contentfooter">')
--- a/web/views/cwproperties.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/cwproperties.py Thu Jul 02 10:35:03 2009 +0200
@@ -188,11 +188,11 @@
def form(self, formid, keys, splitlabel=False):
buttons = [SubmitButton()]
- form = self.vreg.select_object('forms', 'composite', self.req,
- domid=formid, action=self.build_url(),
- form_buttons=buttons,
- onsubmit="return validatePrefsForm('%s')" % formid,
- submitmsg=self.req._('changes applied'))
+ form = self.vreg.select('forms', 'composite', self.req,
+ domid=formid, action=self.build_url(),
+ form_buttons=buttons,
+ onsubmit="return validatePrefsForm('%s')" % formid,
+ submitmsg=self.req._('changes applied'))
path = self.req.relative_path()
if '?' in path:
path, params = path.split('?', 1)
@@ -200,8 +200,8 @@
form.form_add_hidden('__redirectpath', path)
for key in keys:
self.form_row(form, key, splitlabel)
- renderer = self.vreg.select_object('formrenderers', 'cwproperties', self.req,
- display_progress_div=False)
+ renderer = self.vreg.select('formrenderers', 'cwproperties', self.req,
+ display_progress_div=False)
return form.form_render(renderer=renderer)
def form_row(self, form, key, splitlabel):
@@ -210,8 +210,8 @@
label = key.split('.')[-1]
else:
label = key
- subform = self.vreg.select_object('forms', 'base', self.req, entity=entity,
- mainform=False)
+ subform = self.vreg.select('forms', 'base', self.req, entity=entity,
+ mainform=False)
subform.append_field(PropertyValueField(name='value', label=label,
eidparam=True))
subform.vreg = self.vreg
--- a/web/views/editforms.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/editforms.py Thu Jul 02 10:35:03 2009 +0200
@@ -59,19 +59,19 @@
% _('this action is not reversible!'))
# XXX above message should have style of a warning
w(u'<h4>%s</h4>\n' % _('Do you want to delete the following element(s) ?'))
- form = self.vreg.select_object('forms', 'composite', req, domid='deleteconf',
- copy_nav_params=True,
- action=self.build_url('edit'), onsubmit=onsubmit,
- form_buttons=[Button(stdmsgs.YES, cwaction='delete'),
- Button(stdmsgs.NO, cwaction='cancel')])
+ form = self.vreg.select('forms', 'composite', req, domid='deleteconf',
+ copy_nav_params=True,
+ action=self.build_url('edit'), onsubmit=onsubmit,
+ form_buttons=[Button(stdmsgs.YES, cwaction='delete'),
+ Button(stdmsgs.NO, cwaction='cancel')])
done = set()
w(u'<ul>\n')
for entity in self.rset.entities():
if entity.eid in done:
continue
done.add(entity.eid)
- subform = self.vreg.select_object('forms', 'base', req, entity=entity,
- mainform=False)
+ subform = self.vreg.select('forms', 'base', req, entity=entity,
+ mainform=False)
form.form_add_subform(subform)
# don't use outofcontext view or any other that may contain inline edition form
w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'),
@@ -127,12 +127,12 @@
else:
form = self._build_relation_form(entity, value, rtype, role,
row, col, vid, default)
- renderer = self.vreg.select_object('formrenderers', 'base', self.req,
- entity=entity,
- display_label=False, display_help=False,
- display_fields=[(rtype, role)],
- table_class='', button_bar_class='buttonbar',
- display_progress_div=False)
+ renderer = self.vreg.select('formrenderers', 'base', self.req,
+ entity=entity,
+ display_label=False, display_help=False,
+ display_fields=[(rtype, role)],
+ table_class='', button_bar_class='buttonbar',
+ display_progress_div=False)
self.w(form.form_render(renderer=renderer))
def _build_relation_form(self, entity, value, rtype, role, row, col, vid, default):
@@ -145,12 +145,12 @@
% event_data)
cancelclick = "cancelInlineEdit(%s,\'%s\',\'%s\')" % (
entity.eid, rtype, divid)
- form = self.vreg.select_object('forms', 'base', self.req, entity=entity,
- domid='%s-form' % divid, cssstyle='display: none',
- onsubmit=onsubmit, action='#',
- form_buttons=[SubmitButton(),
- Button(stdmsgs.BUTTON_CANCEL,
- onclick=cancelclick)])
+ form = self.vreg.select('forms', 'base', self.req, entity=entity,
+ domid='%s-form' % divid, cssstyle='display: none',
+ onsubmit=onsubmit, action='#',
+ form_buttons=[SubmitButton(),
+ Button(stdmsgs.BUTTON_CANCEL,
+ onclick=cancelclick)])
form.append_field(RelationField(name=rtype, role=role, sort=True,
widget=Select(),
label=u' '))
@@ -167,11 +167,11 @@
Button(stdmsgs.BUTTON_CANCEL,
onclick="cancelInlineEdit(%s,\'%s\',\'%s\')" % (
eid, rtype, divid))]
- form = self.vreg.select_object('forms', 'edition', self.req, self.rset,
- row=row, col=col, form_buttons=buttons,
- domid='%s-form' % divid, action='#',
- cssstyle='display: none',
- onsubmit=self.onsubmit % event_data)
+ form = self.vreg.select('forms', 'edition', self.req, rset=self.rset,
+ row=row, col=col, form_buttons=buttons,
+ domid='%s-form' % divid, action='#',
+ cssstyle='display: none',
+ onsubmit=self.onsubmit % event_data)
self.w(tags.div(value, klass='editableField', id=divid,
ondblclick=self.ondblclick % event_data))
return form
@@ -193,9 +193,9 @@
def render_form(self, entity):
"""fetch and render the form"""
self.form_title(entity)
- form = self.vreg.select_object('forms', 'edition', self.req, entity.rset,
- row=entity.row, col=entity.col, entity=entity,
- submitmsg=self.submited_message())
+ form = self.vreg.select('forms', 'edition', self.req, rset=entity.rset,
+ row=entity.row, col=entity.col, entity=entity,
+ submitmsg=self.submited_message())
self.init_form(form, entity)
self.w(form.form_render(formvid=u'edition'))
@@ -312,9 +312,9 @@
kwargs.setdefault('__redirectrql', rset.printable_rql())
super(TableEditForm, self).__init__(req, rset, **kwargs)
for row in xrange(len(self.rset)):
- form = self.vreg.select_object('forms', 'edition', self.req, self.rset,
- row=row, attrcategories=('primary',),
- mainform=False)
+ form = self.vreg.select('forms', 'edition', self.req, rset=self.rset,
+ row=row, attrcategories=('primary',),
+ mainform=False)
# XXX rely on the EntityCompositeFormRenderer to put the eid input
form.remove_field(form.field_by_name('eid'))
self.form_add_subform(form)
@@ -330,7 +330,7 @@
should be the eid
"""
#self.form_title(entity)
- form = self.vreg.select_object('forms', self.id, self.req, self.rset)
+ form = self.vreg.select('forms', self.id, self.req, rset=self.rset)
self.w(form.form_render())
@@ -361,9 +361,9 @@
def render_form(self, entity, peid, rtype, role, **kwargs):
"""fetch and render the form"""
- form = self.vreg.select_object('forms', 'edition', self.req, None,
- entity=entity, form_renderer_id='inline',
- mainform=False, copy_nav_params=False)
+ form = self.vreg.select('forms', 'edition', self.req, entity=entity,
+ form_renderer_id='inline', mainform=False,
+ copy_nav_params=False)
self.add_hiddens(form, entity, peid, rtype, role)
divid = '%s-%s-%s' % (peid, rtype, entity.eid)
title = self.schema.rschema(rtype).display_name(self.req, role)
--- a/web/views/editviews.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/editviews.py Thu Jul 02 10:35:03 2009 +0200
@@ -120,8 +120,7 @@
eid = entity.eid
pending_inserts = self.req.get_pending_inserts(eid)
rtype = rschema.type
- form = self.vreg.select_object('forms', 'edition', self.req,
- self.rset, entity=entity)
+ form = self.vreg.select('forms', 'edition', self.req, entity=entity)
field = form.field_by_name(rschema, target, entity.e_schema)
limit = self.req.property_value('navigation.combobox-limit')
for eview, reid in form.form_field_vocabulary(field, limit):
--- a/web/views/facets.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/facets.py Thu Jul 02 10:35:03 2009 +0200
@@ -110,7 +110,7 @@
cubicweb.info('after facets with rql: %s' % repr(rqlst))
def get_facets(self, rset, mainvar):
- return self.vreg.possible_vobjects('facets', self.req, rset,
+ return self.vreg.possible_vobjects('facets', self.req, rset=rset,
context='facetbox',
filtered_variable=mainvar)
--- a/web/views/formrenderers.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/formrenderers.py Thu Jul 02 10:35:03 2009 +0200
@@ -435,8 +435,6 @@
"""create a form to edit entity's inlined relations"""
if not hasattr(form, 'inlined_relations'):
return
- entity = form.edited_entity
- __ = self.req.__
for rschema, targettypes, role in form.inlined_relations():
# show inline forms only if there's one possible target type
# for rschema
@@ -447,37 +445,42 @@
continue
targettype = targettypes[0].type
if form.should_inline_relation_form(rschema, targettype, role):
- w(u'<div id="inline%sslot">' % rschema)
- existant = entity.has_eid() and entity.related(rschema)
- if existant:
- # display inline-edition view for all existing related entities
- w(form.view('inline-edition', existant, rtype=rschema, role=role,
- ptype=entity.e_schema, peid=entity.eid))
- if role == 'subject':
- card = rschema.rproperty(entity.e_schema, targettype, 'cardinality')[0]
- else:
- card = rschema.rproperty(targettype, entity.e_schema, 'cardinality')[1]
- # there is no related entity and we need at least one: we need to
- # display one explicit inline-creation view
- if form.should_display_inline_creation_form(rschema, existant, card):
- w(form.view('inline-creation', None, etype=targettype,
- peid=entity.eid, ptype=entity.e_schema,
- rtype=rschema, role=role))
- # we can create more than one related entity, we thus display a link
- # to add new related entities
- if form.should_display_add_new_relation_link(rschema, existant, card):
- divid = "addNew%s%s%s:%s" % (targettype, rschema, role, entity.eid)
- w(u'<div class="inlinedform" id="%s" cubicweb:limit="true">'
- % divid)
- js = "addInlineCreationForm('%s', '%s', '%s', '%s')" % (
- entity.eid, targettype, rschema, role)
- if card in '1?':
- js = "toggleVisibility('%s'); %s" % (divid, js)
- w(u'<a class="addEntity" id="add%s:%slink" href="javascript: %s" >+ %s.</a>'
- % (rschema, entity.eid, js, __('add a %s' % targettype)))
- w(u'</div>')
- w(u'<div class="trame_grise"> </div>')
- w(u'</div>')
+ self.inline_relation_form(w, form, rschema, targettype, role)
+
+ def inline_relation_form(self, w, form, rschema, targettype, role):
+ entity = form.edited_entity
+ __ = self.req.__
+ w(u'<div id="inline%sslot">' % rschema)
+ existant = entity.has_eid() and entity.related(rschema)
+ if existant:
+ # display inline-edition view for all existing related entities
+ w(form.view('inline-edition', existant, rtype=rschema, role=role,
+ ptype=entity.e_schema, peid=entity.eid))
+ if role == 'subject':
+ card = rschema.rproperty(entity.e_schema, targettype, 'cardinality')[0]
+ else:
+ card = rschema.rproperty(targettype, entity.e_schema, 'cardinality')[1]
+ # there is no related entity and we need at least one: we need to
+ # display one explicit inline-creation view
+ if form.should_display_inline_creation_form(rschema, existant, card):
+ w(form.view('inline-creation', None, etype=targettype,
+ peid=entity.eid, ptype=entity.e_schema,
+ rtype=rschema, role=role))
+ # we can create more than one related entity, we thus display a link
+ # to add new related entities
+ if form.should_display_add_new_relation_link(rschema, existant, card):
+ divid = "addNew%s%s%s:%s" % (targettype, rschema, role, entity.eid)
+ w(u'<div class="inlinedform" id="%s" cubicweb:limit="true">'
+ % divid)
+ js = "addInlineCreationForm('%s', '%s', '%s', '%s')" % (
+ entity.eid, targettype, rschema, role)
+ if card in '1?':
+ js = "toggleVisibility('%s'); %s" % (divid, js)
+ w(u'<a class="addEntity" id="add%s:%slink" href="javascript: %s" >+ %s.</a>'
+ % (rschema, entity.eid, js, __('add a %s' % targettype)))
+ w(u'</div>')
+ w(u'<div class="trame_grise"> </div>')
+ w(u'</div>')
class EntityInlinedFormRenderer(EntityFormRenderer):
--- a/web/views/forms.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/forms.py Thu Jul 02 10:35:03 2009 +0200
@@ -145,9 +145,9 @@
return renderer.render(self, values)
def form_default_renderer(self):
- return self.vreg.select_object('formrenderers', self.form_renderer_id,
- self.req, self.rset,
- row=self.row, col=self.col)
+ return self.vreg.select('formrenderers', self.form_renderer_id,
+ self.req, rset=self.rset,
+ row=self.row, col=self.col)
def form_build_context(self, rendervalues=None):
"""build form context values (the .context attribute which is a
@@ -332,10 +332,9 @@
return value
def form_default_renderer(self):
- return self.vreg.select_object('formrenderers', self.form_renderer_id,
- self.req, self.rset,
- row=self.row, col=self.col,
- entity=self.edited_entity)
+ return self.vreg.select('formrenderers', self.form_renderer_id,
+ self.req, rset=self.rset, row=self.row,
+ col=self.col, entity=self.edited_entity)
def form_build_context(self, values=None):
"""overriden to add edit[s|o] hidden fields and to ensure schema fields
--- a/web/views/iprogress.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/iprogress.py Thu Jul 02 10:35:03 2009 +0200
@@ -5,8 +5,8 @@
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
-
__docformat__ = "restructuredtext en"
+_ = unicode
from logilab.mtconverter import html_escape
@@ -168,7 +168,8 @@
id = 'ic_progress_table_view'
def call(self):
- view = self.vreg.select_view('progress_table_view', self.req, self.rset)
+ view = self.vreg.select('views', 'progress_table_view', self.req,
+ rset=self.rset)
columns = list(view.columns)
try:
columns.remove('project')
--- a/web/views/management.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/management.py Thu Jul 02 10:35:03 2009 +0200
@@ -107,13 +107,12 @@
def owned_by_edit_form(self, entity):
self.w('<h3>%s</h3>' % self.req._('ownership'))
msg = self.req._('ownerships have been changed')
- form = self.vreg.select_object('forms', 'base', self.req, entity=entity,
- form_renderer_id='base',
- submitmsg=msg,
- form_buttons=[formwidgets.SubmitButton()],
- domid='ownership%s' % entity.eid,
- __redirectvid='security',
- __redirectpath=entity.rest_path())
+ form = self.vreg.select('forms', 'base', self.req, entity=entity,
+ form_renderer_id='base', submitmsg=msg,
+ form_buttons=[formwidgets.SubmitButton()],
+ domid='ownership%s' % entity.eid,
+ __redirectvid='security',
+ __redirectpath=entity.rest_path())
field = guess_field(entity.e_schema, self.schema.rschema('owned_by'))
form.append_field(field)
self.w(form.form_render(display_progress_div=False))
@@ -166,11 +165,11 @@
newperm = self.vreg.etype_class('CWPermission')(self.req, None)
newperm.eid = self.req.varmaker.next()
w(u'<p>%s</p>' % _('add a new permission'))
- form = self.vreg.select_object('forms', 'base', self.req, entity=newperm,
- form_buttons=[formwidgets.SubmitButton()],
- domid='reqperm%s' % entity.eid,
- __redirectvid='security',
- __redirectpath=entity.rest_path())
+ form = self.vreg.select('forms', 'base', self.req, entity=newperm,
+ form_buttons=[formwidgets.SubmitButton()],
+ domid='reqperm%s' % entity.eid,
+ __redirectvid='security',
+ __redirectpath=entity.rest_path())
form.form_add_hidden('require_permission', entity.eid, role='object',
eidparam=True)
permnames = getattr(entity, '__permissions__', None)
@@ -186,8 +185,8 @@
form.append_field(field)
field = guess_field(cwpermschema, self.schema.rschema('require_group'))
form.append_field(field)
- renderer = self.vreg.select_object('formrenderers', 'htable', self.req,
- rset=None, display_progress_div=False)
+ renderer = self.vreg.select('formrenderers', 'htable', self.req,
+ rset=None, display_progress_div=False)
self.w(form.form_render(renderer=renderer))
@@ -244,8 +243,8 @@
submiturl = self.config['submit-url']
submitmail = self.config['submit-mail']
if submiturl or submitmail:
- form = self.vreg.select_object('forms', 'base', self.req, rset=None,
- mainform=False)
+ form = self.vreg.select('forms', 'base', self.req, rset=None,
+ mainform=False)
binfo = text_error_description(ex, excinfo, req, eversion, cversions)
form.form_add_hidden('description', binfo)
form.form_add_hidden('__bugreporting', '1')
--- a/web/views/massmailing.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/massmailing.py Thu Jul 02 10:35:03 2009 +0200
@@ -126,6 +126,6 @@
req.add_js('cubicweb.widgets.js')
req.add_css('cubicweb.mailform.css')
from_addr = '%s <%s>' % (req.user.dc_title(), req.user.get_email())
- form = self.vreg.select_object('forms', 'massmailing', self.req, self.rset,
- action='sendmail', domid='sendmail')
+ form = self.vreg.select('forms', 'massmailing', self.req, rset=self.rset,
+ action='sendmail', domid='sendmail')
self.w(form.form_render(sender=from_addr))
--- a/web/views/navigation.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/navigation.py Thu Jul 02 10:35:03 2009 +0200
@@ -6,6 +6,7 @@
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
+_ = unicode
from rql.nodes import VariableRef, Constant
@@ -19,8 +20,6 @@
from cubicweb.common.uilib import cut
from cubicweb.web.component import EntityVComponent, NavigationComponent
-_ = unicode
-
class PageNavigation(NavigationComponent):
@@ -49,6 +48,7 @@
def index_display(self, start, stop):
return u'%s - %s' % (start+1, stop+1)
+
class SortedNavigation(NavigationComponent):
"""sorted navigation apply if navigation is needed (according to page size)
and if the result set is sorted
@@ -148,21 +148,21 @@
def limit_rset_using_paged_nav(self, req, rset, w, forcedisplay=False,
show_all_option=True, page_size=None):
- showall = forcedisplay or req.form.get('__force_display') is not None
- nav = not showall and self.vreg.select_component('navigation', req, rset,
- page_size=page_size)
- if nav:
- # get boundaries before component rendering
- start, stop = nav.page_boundaries()
- nav.render(w=w)
- params = dict(req.form)
- nav.clean_params(params)
- # make a link to see them all
- if show_all_option:
- url = html_escape(self.build_url(__force_display=1, **params))
- w(u'<p><a href="%s">%s</a></p>\n'
- % (url, req._('show %s results') % len(rset)))
- rset.limit(offset=start, limit=stop-start, inplace=True)
+ if not (forcedisplay or req.form.get('__force_display') is not None):
+ nav = self.vreg.select_object('components', 'navigation', req,
+ rset=rset, page_size=page_size)
+ if nav:
+ # get boundaries before component rendering
+ start, stop = nav.page_boundaries()
+ nav.render(w=w)
+ params = dict(req.form)
+ nav.clean_params(params)
+ # make a link to see them all
+ if show_all_option:
+ url = html_escape(self.build_url(__force_display=1, **params))
+ w(u'<p><a href="%s">%s</a></p>\n'
+ % (url, req._('show %s results') % len(rset)))
+ rset.limit(offset=start, limit=stop-start, inplace=True)
# monkey patch base View class to add a .pagination(req, rset, w, forcedisplay)
--- a/web/views/owl.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/owl.py Thu Jul 02 10:35:03 2009 +0200
@@ -6,14 +6,14 @@
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
+_ = unicode
from logilab.mtconverter import TransformError, xml_escape
from cubicweb.view import StartupView, EntityView
+from cubicweb.selectors import none_rset, match_view
from cubicweb.web.action import Action
-from cubicweb.selectors import none_rset, match_view
-
-_ = unicode
+from cubicweb.web.views import schema
OWL_CARD_MAP = {'1': '<rdf:type rdf:resource="&owl;FunctionalProperty"/>',
'?': '<owl:maxCardinality rdf:datatype="&xsd;int">1</owl:maxCardinality>',
@@ -55,8 +55,6 @@
OWL_CLOSING_ROOT = u'</rdf:RDF>'
-DEFAULT_SKIP_RELS = frozenset(('is', 'is_instance_of', 'identity',
- 'owned_by', 'created_by'))
class OWLView(StartupView):
"""This view export in owl format schema database. It is the TBOX"""
@@ -69,36 +67,36 @@
skipmeta = int(self.req.form.get('skipmeta', True))
if writeprefix:
self.w(OWL_OPENING_ROOT % {'appid': self.schema.name})
- self.visit_schema(skipmeta=skipmeta)
+ self.visit_schema(skiptypes=skipmeta and schema.SKIP_TYPES or ())
if writeprefix:
self.w(OWL_CLOSING_ROOT)
- def visit_schema(self, skiprels=DEFAULT_SKIP_RELS, skipmeta=True):
+ def should_display_rschema(self, rschema):
+ return not rschema in self.skiptypes and (
+ rschema.has_local_role('read') or
+ rschema.has_perm(self.req, 'read'))
+
+ def visit_schema(self, skiptypes):
"""get a layout for a whole schema"""
- entities = sorted([eschema for eschema in self.schema.entities()
- if not eschema.is_final()])
- if skipmeta:
- entities = [eschema for eschema in entities
- if not eschema.meta]
+ self.skiptypes = skiptypes
+ entities = sorted(eschema for eschema in self.schema.entities()
+ if not eschema.is_final() or eschema in skiptypes)
self.w(u'<!-- classes definition -->')
for eschema in entities:
- self.visit_entityschema(eschema, skiprels)
+ self.visit_entityschema(eschema)
self.w(u'<!-- property definition -->')
- self.visit_property_schema(eschema, skiprels)
+ self.visit_property_schema(eschema)
self.w(u'<!-- datatype property -->')
self.visit_property_object_schema(eschema)
- def visit_entityschema(self, eschema, skiprels=()):
+ def visit_entityschema(self, eschema):
"""get a layout for an entity OWL schema"""
self.w(u'<owl:Class rdf:ID="%s">'% eschema)
self.w(u'<!-- relations -->')
for rschema, targetschemas, role in eschema.relation_definitions():
- if rschema.type in skiprels:
- continue
- if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
+ if not self.should_display_rschema(rschema):
continue
for oeschema in targetschemas:
- label = rschema.type
if role == 'subject':
card = rschema.rproperty(eschema, oeschema, 'cardinality')[0]
else:
@@ -110,58 +108,44 @@
<owl:onProperty rdf:resource="#%s"/>
%s
</owl:Restriction>
-</rdfs:subClassOf>
-''' % (label, cardtag))
+</rdfs:subClassOf>''' % (rschema, cardtag))
self.w(u'<!-- attributes -->')
-
for rschema, aschema in eschema.attribute_definitions():
- if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
- continue
- aname = rschema.type
- if aname == 'eid':
+ if not self.should_display_rschema(rschema):
continue
self.w(u'''<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#%s"/>
<rdf:type rdf:resource="&owl;FunctionalProperty"/>
</owl:Restriction>
-</rdfs:subClassOf>'''
- % aname)
+</rdfs:subClassOf>''' % rschema)
self.w(u'</owl:Class>')
- def visit_property_schema(self, eschema, skiprels=()):
+ def visit_property_schema(self, eschema):
"""get a layout for property entity OWL schema"""
for rschema, targetschemas, role in eschema.relation_definitions():
- if rschema.type in skiprels:
- continue
- if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
+ if not self.should_display_rschema(rschema):
continue
for oeschema in targetschemas:
label = rschema.type
self.w(u'''<owl:ObjectProperty rdf:ID="%s">
<rdfs:domain rdf:resource="#%s"/>
<rdfs:range rdf:resource="#%s"/>
-</owl:ObjectProperty>
-''' % (label, eschema, oeschema.type))
+</owl:ObjectProperty>''' % (label, eschema, oeschema.type))
def visit_property_object_schema(self, eschema):
for rschema, aschema in eschema.attribute_definitions():
- if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
- continue
- aname = rschema.type
- if aname == 'eid':
+ if not self.should_display_rschema(rschema):
continue
self.w(u'''<owl:DatatypeProperty rdf:ID="%s">
<rdfs:domain rdf:resource="#%s"/>
<rdfs:range rdf:resource="%s"/>
-</owl:DatatypeProperty>'''
- % (aname, eschema, OWL_TYPE_MAP[aschema.type]))
+</owl:DatatypeProperty>''' % (aname, eschema, OWL_TYPE_MAP[aschema.type]))
class OWLABOXView(EntityView):
'''This view represents a part of the ABOX for a given entity.'''
-
id = 'owlabox'
title = _('owlabox')
templatable = False
@@ -173,8 +157,8 @@
self.cell_call(i, 0)
self.w(OWL_CLOSING_ROOT)
- def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS):
- self.wview('owlaboxitem', self.rset, row=row, col=col, skiprels=skiprels)
+ def cell_call(self, row, col):
+ self.wview('owlaboxitem', self.rset, row=row, col=col)
class OWLABOXItemView(EntityView):
@@ -183,13 +167,13 @@
templatable = False
content_type = 'application/xml' # 'text/xml'
- def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS):
+ def cell_call(self, row, col):
entity = self.complete_entity(row, col)
eschema = entity.e_schema
self.w(u'<%s rdf:ID="%s">' % (eschema, entity.eid))
self.w(u'<!--attributes-->')
for rschema, aschema in eschema.attribute_definitions():
- if rschema.type in skiprels:
+ if rschema.meta:
continue
if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
continue
@@ -204,7 +188,7 @@
pass
self.w(u'<!--relations -->')
for rschema, targetschemas, role in eschema.relation_definitions():
- if rschema.type in skiprels:
+ if rschema.meta:
continue
if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
continue
--- a/web/views/primary.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/primary.py Thu Jul 02 10:35:03 2009 +0200
@@ -89,8 +89,8 @@
def content_navigation_components(self, context):
self.w(u'<div class="%s">' % context)
- for comp in self.vreg.possible_vobjects('contentnavigation',
- self.req, self.rset, row=self.row,
+ for comp in self.vreg.possible_vobjects('contentnavigation', self.req,
+ rset=self.rset, row=self.row,
view=self, context=context):
try:
comp.render(w=self.w, row=self.row, view=self)
@@ -178,7 +178,7 @@
label = display_name(self.req, rschema.type, role)
vid = dispctrl.get('vid', 'sidebox')
sideboxes.append( (label, rset, vid) )
- sideboxes += self.vreg.possible_vobjects('boxes', self.req, self.rset,
+ sideboxes += self.vreg.possible_vobjects('boxes', self.req, rset=self.rset,
row=self.row, view=self,
context='incontext')
return sideboxes
--- a/web/views/schema.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/schema.py Thu Jul 02 10:35:03 2009 +0200
@@ -7,12 +7,11 @@
"""
__docformat__ = "restructuredtext en"
-from itertools import cycle
-
from logilab.mtconverter import html_escape
from yams import schema2dot as s2d
from cubicweb.selectors import implements, yes
+from cubicweb.schema import META_RELATIONS_TYPES, SCHEMA_TYPES
from cubicweb.schemaviewer import SchemaViewer
from cubicweb.view import EntityView, StartupView
from cubicweb.common import tags, uilib
@@ -20,6 +19,14 @@
from cubicweb.web.views import TmpFileViewMixin, primary, baseviews, tabs
from cubicweb.web.facet import AttributeFacet
+SKIP_TYPES = set()
+SKIP_TYPES.update(META_RELATIONS_TYPES)
+SKIP_TYPES.update(SCHEMA_TYPES)
+
+def skip_types(req):
+ if int(req.form.get('skipmeta', True)):
+ return schema.SKIP_TYPES
+ return ()
class ViewSchemaAction(action.Action):
id = 'schema'
@@ -57,14 +64,11 @@
if final:
self.w(u'</em>')
-SKIPPED_RELS = ('is', 'is_instance_of', 'identity', 'created_by', 'owned_by',
- 'has_text',)
class CWETypePrimaryView(tabs.TabsMixin, primary.PrimaryView):
__select__ = implements('CWEType')
title = _('in memory entity schema')
main_related_section = False
- skip_rels = SKIPPED_RELS
tabs = [_('cwetype-schema-text'), _('cwetype-schema-image'),
_('cwetype-schema-permissions'), _('cwetype-workflow')]
default_tab = 'cwetype-schema-text'
@@ -183,94 +187,54 @@
# schema images ###############################################################
-class RestrictedSchemaDotPropsHandler(s2d.SchemaDotPropsHandler):
- def __init__(self, req):
- # FIXME: colors are arbitrary
- self.nextcolor = cycle( ('#aa0000', '#00aa00', '#0000aa',
- '#000000', '#888888') ).next
+class RestrictedSchemaVisitorMixIn(object):
+ def __init__(self, req, *args, **kwargs):
+ super(RestrictedSchemaVisitorMixIn, self).__init__(*args, **kwargs)
self.req = req
- def display_attr(self, rschema):
- return not rschema.meta and (rschema.has_local_role('read')
- or rschema.has_perm(self.req, 'read'))
+ def should_display_schema(self, schema):
+ return (super(RestrictedSchemaVisitorMixIn, self).should_display_schema(schema)
+ and rschema.has_local_role('read') or rschema.has_perm(self.req, 'read'))
- # XXX remove this method once yams > 0.20 is out
- def node_properties(self, eschema):
- """return default DOT drawing options for an entity schema"""
- label = ['{', eschema.type, '|']
- label.append(r'\l'.join(rel.type for rel in eschema.subject_relations()
- if rel.final and self.display_attr(rel)))
- label.append(r'\l}') # trailing \l ensure alignement of the last one
- return {'label' : ''.join(label), 'shape' : "record",
- 'fontname' : "Courier", 'style' : "filled"}
-
- def edge_properties(self, rschema, subjnode, objnode):
- kwargs = super(RestrictedSchemaDotPropsHandler, self).edge_properties(rschema, subjnode, objnode)
- # symetric rels are handled differently, let yams decide what's best
- if not rschema.symetric:
- kwargs['color'] = self.nextcolor()
- kwargs['fontcolor'] = kwargs['color']
- # dot label decoration is just awful (1 line underlining the label
- # + 1 line going to the closest edge spline point)
- kwargs['decorate'] = 'false'
- return kwargs
+ def should_display_attr(self, schema):
+ return (super(RestrictedSchemaVisitorMixIn, self).should_display_attr(schema)
+ and rschema.has_local_role('read') or rschema.has_perm(self.req, 'read'))
-class RestrictedSchemaVisitorMiIn:
- def __init__(self, req, *args, **kwargs):
- # hack hack hack
- assert len(self.__class__.__bases__) == 2
- self.__parent = self.__class__.__bases__[1]
- self.__parent.__init__(self, *args, **kwargs)
- self.req = req
-
- def nodes(self):
- for etype, eschema in self.__parent.nodes(self):
- if eschema.has_local_role('read') or eschema.has_perm(self.req, 'read'):
- yield eschema.type, eschema
-
- def edges(self):
- for setype, oetype, rschema in self.__parent.edges(self):
- if rschema.has_local_role('read') or rschema.has_perm(self.req, 'read'):
- yield setype, oetype, rschema
-
-
-class FullSchemaVisitor(RestrictedSchemaVisitorMiIn, s2d.FullSchemaVisitor):
+class FullSchemaVisitor(RestrictedSchemaVisitorMixIn, s2d.FullSchemaVisitor):
pass
-class OneHopESchemaVisitor(RestrictedSchemaVisitorMiIn, s2d.OneHopESchemaVisitor):
+class OneHopESchemaVisitor(RestrictedSchemaVisitorMixIn,
+ s2d.OneHopESchemaVisitor):
pass
-class OneHopRSchemaVisitor(RestrictedSchemaVisitorMiIn, s2d.OneHopRSchemaVisitor):
+class OneHopRSchemaVisitor(RestrictedSchemaVisitorMixIn,
+ s2d.OneHopRSchemaVisitor):
pass
class SchemaImageView(TmpFileViewMixin, StartupView):
id = 'schemagraph'
+ content_type = 'image/png'
- content_type = 'image/png'
- skip_rels = SKIPPED_RELS
def _generate(self, tmpfile):
"""display global schema information"""
- skipmeta = not int(self.req.form.get('withmeta', 0))
- visitor = FullSchemaVisitor(self.req, self.schema, skiprels=self.skip_rels, skipmeta=skipmeta)
- s2d.schema2dot(outputfile=tmpfile, visitor=visitor,
- prophdlr=RestrictedSchemaDotPropsHandler(self.req))
+ visitor = FullSchemaVisitor(self.req, self.schema,
+ skiptypes=skip_types(self.req))
+ s2d.schema2dot(outputfile=tmpfile, visitor=visitor)
class CWETypeSchemaImageView(TmpFileViewMixin, EntityView):
id = 'schemagraph'
__select__ = implements('CWEType')
-
content_type = 'image/png'
- skip_rels = SKIPPED_RELS
def _generate(self, tmpfile):
"""display schema information for an entity"""
entity = self.entity(self.row, self.col)
eschema = self.vreg.schema.eschema(entity.name)
- visitor = OneHopESchemaVisitor(self.req, eschema, skiprels=self.skip_rels)
- s2d.schema2dot(outputfile=tmpfile, visitor=visitor,
- prophdlr=RestrictedSchemaDotPropsHandler(self.req))
+ visitor = OneHopESchemaVisitor(self.req, eschema,
+ skiptypes=skip_types(self.req))
+ s2d.schema2dot(outputfile=tmpfile, visitor=visitor)
class CWRTypeSchemaImageView(CWETypeSchemaImageView):
__select__ = implements('CWRType')
@@ -280,8 +244,7 @@
entity = self.entity(self.row, self.col)
rschema = self.vreg.schema.rschema(entity.name)
visitor = OneHopRSchemaVisitor(self.req, rschema)
- s2d.schema2dot(outputfile=tmpfile, visitor=visitor,
- prophdlr=RestrictedSchemaDotPropsHandler(self.req))
+ s2d.schema2dot(outputfile=tmpfile, visitor=visitor)
### facets
--- a/web/views/startup.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/startup.py Thu Jul 02 10:35:03 2009 +0200
@@ -14,10 +14,10 @@
from cubicweb.view import StartupView
from cubicweb.selectors import match_user_groups, implements
+from cubicweb.schema import META_RELATIONS_TYPES
from cubicweb.common.uilib import ureport_as_html
from cubicweb.web import ajax_replace_url, uicfg, httpcache
-from cubicweb.web.views import tabs
-from cubicweb.web.views.management import SecurityViewMixIn
+from cubicweb.web.views import tabs, management, schema as schemamod
class ManageView(StartupView):
id = 'manage'
@@ -31,8 +31,6 @@
uicfg.indexview_etype_section.setdefault(eschema, 'schema')
elif eschema.is_subobject(strict=True):
uicfg.indexview_etype_section.setdefault(eschema, 'subobject')
- elif eschema.meta:
- uicfg.indexview_etype_section.setdefault(eschema, 'system')
else:
uicfg.indexview_etype_section.setdefault(eschema, 'application')
@@ -80,7 +78,7 @@
def folders(self):
self.w(u'<h4>%s</h4>\n' % self.req._('Browse by category'))
- self.vreg.select_view('tree', self.req, None).render(w=self.w)
+ self.vreg.select('views', 'tree', self.req).render(w=self.w)
def startup_views(self):
self.w(u'<h4>%s</h4>\n' % self.req._('Startup views'))
@@ -140,7 +138,8 @@
label = display_name(req, etype, 'plural')
nb = req.execute('Any COUNT(X) WHERE X is %s' % etype)[0][0]
if nb > 1:
- view = self.vreg.select_view('list', req, req.etype_rset(etype))
+ view = self.vreg.select('views', 'list', req,
+ rset=req.etype_rset(etype))
url = view.url()
else:
url = self.build_url('view', rql='%s X' % etype)
@@ -185,9 +184,9 @@
self.w(_(u'<div>This schema of the data model <em>excludes</em> the '
u'meta-data, but you can also display a <a href="%s">complete '
u'schema with meta-data</a>.</div>')
- % html_escape(self.build_url('view', vid='schemagraph', withmeta=1)))
+ % html_escape(self.build_url('view', vid='schemagraph', skipmeta=0)))
self.w(u'<img src="%s" alt="%s"/>\n' % (
- html_escape(self.req.build_url('view', vid='schemagraph', withmeta=0)),
+ html_escape(self.req.build_url('view', vid='schemagraph', skipmeta=1)),
self.req._("graphical representation of the application'schema")))
@@ -200,46 +199,43 @@
self.wview('table', rset, displayfilter=True)
-class ManagerSchemaPermissionsView(StartupView, SecurityViewMixIn):
+class ManagerSchemaPermissionsView(StartupView, management.SecurityViewMixIn):
id = 'schema-security'
__select__ = StartupView.__select__ & match_user_groups('managers')
- def call(self, display_relations=True,
- skiprels=('is', 'is_instance_of', 'identity', 'owned_by', 'created_by')):
+ def call(self, display_relations=True):
self.req.add_css('cubicweb.acl.css')
- _ = self.req._
+ skiptypes = schemamod.skip_types(self.req)
formparams = {}
formparams['sec'] = self.id
- formparams['withmeta'] = int(self.req.form.get('withmeta', True))
+ if not skiptypes:
+ formparams['skipmeta'] = u'0'
schema = self.schema
# compute entities
- entities = [eschema for eschema in schema.entities()
- if not eschema.is_final()]
- if not formparams['withmeta']:
- entities = [eschema for eschema in entities
- if not eschema.meta]
+ entities = sorted(eschema for eschema in schema.entities()
+ if not (eschema.is_final() or eschema in skiptypes))
# compute relations
if display_relations:
- relations = [rschema for rschema in schema.relations()
- if not (rschema.is_final() or rschema.type in skiprels)]
- if not formparams['withmeta']:
- relations = [rschema for rschema in relations
- if not rschema.meta]
+ relations = sorted(rschema for rschema in schema.relations()
+ if not (rschema.is_final()
+ or rschema in skiptypes
+ or rschema in META_RELATIONS_TYPES))
else:
relations = []
# index
+ _ = self.req._
self.w(u'<div id="schema_security"><a id="index" href="index"/>')
self.w(u'<h2 class="schema">%s</h2>' % _('index').capitalize())
self.w(u'<h4>%s</h4>' % _('Entities').capitalize())
ents = []
- for eschema in sorted(entities):
+ for eschema in entities:
url = html_escape(self.build_url('schema', **formparams))
ents.append(u'<a class="grey" href="%s#%s">%s</a> (%s)' % (
url, eschema.type, eschema.type, _(eschema.type)))
self.w(u', '.join(ents))
self.w(u'<h4>%s</h4>' % (_('relations').capitalize()))
rels = []
- for rschema in sorted(relations):
+ for rschema in relations:
url = html_escape(self.build_url('schema', **formparams))
rels.append(u'<a class="grey" href="%s#%s">%s</a> (%s), ' % (
url , rschema.type, rschema.type, _(rschema.type)))
@@ -255,15 +251,15 @@
_ = self.req._
self.w(u'<a id="entities" href="entities"/>')
self.w(u'<h2 class="schema">%s</h2>' % _('permissions for entities').capitalize())
- for eschema in sorted(entities):
+ for eschema in entities:
self.w(u'<a id="%s" href="%s"/>' % (eschema.type, eschema.type))
self.w(u'<h3 class="schema">%s (%s) ' % (eschema.type, _(eschema.type)))
url = html_escape(self.build_url('schema', **formparams) + '#index')
- self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (url, self.req.external_resource('UP_ICON'), _('up')))
+ self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (
+ url, self.req.external_resource('UP_ICON'), _('up')))
self.w(u'</h3>')
self.w(u'<div style="margin: 0px 1.5em">')
self.schema_definition(eschema, link=False)
-
# display entity attributes only if they have some permissions modified
modified_attrs = []
for attr, etype in eschema.attribute_definitions():
@@ -276,29 +272,29 @@
for attr in modified_attrs:
self.w(u'<h4 class="schema">%s (%s)</h4> ' % (attr.type, _(attr.type)))
self.schema_definition(attr, link=False)
- self.w(u'</div>')
- else:
- self.w(u'</div>')
-
+ self.w(u'</div>')
def display_relations(self, relations, formparams):
_ = self.req._
self.w(u'<a id="relations" href="relations"/>')
self.w(u'<h2 class="schema">%s </h2>' % _('permissions for relations').capitalize())
- for rschema in sorted(relations):
+ for rschema in relations:
self.w(u'<a id="%s" href="%s"/>' % (rschema.type, rschema.type))
self.w(u'<h3 class="schema">%s (%s) ' % (rschema.type, _(rschema.type)))
url = html_escape(self.build_url('schema', **formparams) + '#index')
- self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (url, self.req.external_resource('UP_ICON'), _('up')))
+ self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (
+ url, self.req.external_resource('UP_ICON'), _('up')))
self.w(u'</h3>')
self.w(u'<div style="margin: 0px 1.5em">')
subjects = [str(subj) for subj in rschema.subjects()]
- self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (_('subject_plural:'),
- ', '.join( [str(subj) for subj in rschema.subjects()]),
- ', '.join( [_(str(subj)) for subj in rschema.subjects()])))
- self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (_('object_plural:'),
- ', '.join( [str(obj) for obj in rschema.objects()]),
- ', '.join( [_(str(obj)) for obj in rschema.objects()])))
+ self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (
+ _('subject_plural:'),
+ ', '.join(str(subj) for subj in rschema.subjects()),
+ ', '.join(_(str(subj)) for subj in rschema.subjects())))
+ self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (
+ _('object_plural:'),
+ ', '.join(str(obj) for obj in rschema.objects()),
+ ', '.join(_(str(obj)) for obj in rschema.objects())))
self.schema_definition(rschema, link=False)
self.w(u'</div>')
@@ -308,13 +304,13 @@
def call(self):
from cubicweb.schemaviewer import SchemaViewer
- skipmeta = int(self.req.form.get('skipmeta', True))
- schema = self.schema
+ if int(self.req.form.get('skipmeta', True)):
+ skip = schema.SKIP_TYPES
+ else:
+ skip = ()
viewer = SchemaViewer(self.req)
- layout = viewer.visit_schema(schema, display_relations=True,
- skiprels=('is', 'is_instance_of', 'identity',
- 'owned_by', 'created_by'),
- skipmeta=skipmeta)
+ layout = viewer.visit_schema(self.schema, display_relations=True,
+ skiptypes=skip)
self.w(ureport_as_html(layout))
--- a/web/views/tableview.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/tableview.py Thu Jul 02 10:35:03 2009 +0200
@@ -35,7 +35,7 @@
rqlst.save_state()
mainvar, baserql = prepare_facets_rqlst(rqlst, self.rset.args)
wdgs = [facet.get_widget() for facet in self.vreg.possible_vobjects(
- 'facets', self.req, self.rset, context='tablefilter',
+ 'facets', self.req, rset=self.rset, context='tablefilter',
filtered_variable=mainvar)]
wdgs = [wdg for wdg in wdgs if wdg is not None]
rqlst.recover()
--- a/web/views/tabs.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/tabs.py Thu Jul 02 10:35:03 2009 +0200
@@ -86,7 +86,7 @@
selected_tabs = []
for tab in tabs:
try:
- self.vreg.select_view(tab, self.req, self.rset)
+ self.vreg.select('views', tab, self.req, rset=self.rset)
selected_tabs.append(tab)
except NoSelectableObject:
continue
@@ -109,8 +109,8 @@
#if rql:
# self.req.execute(rql).get_entity(0,0).view(default, w=self.w)
# return
- self.req.add_css('ui.tabs.css')
- self.req.add_js(('ui.core.js', 'ui.tabs.js',
+ self.req.add_css('tabs-no-images.css')
+ self.req.add_js(('jquery.tools.min.js', 'cubicweb.htmlhelpers.js',
'cubicweb.ajax.js', 'cubicweb.tabs.js', 'cubicweb.lazy.js'))
# prune tabs : not all are to be shown
tabs = self.prune_tabs(tabs)
@@ -123,7 +123,7 @@
else:
uid = make_uid('tab')
w(u'<div id="entity-tabs-%s">' % uid)
- w(u'<ul>')
+ w(u'<ul class="css-tabs" id="tabs-%s">' % entity.eid)
for tab in tabs:
w(u'<li>')
w(u'<a href="#as-%s">' % tab)
@@ -134,22 +134,25 @@
w(u'</li>')
w(u'</ul>')
w(u'</div>')
+ w(u'<div id="panes-%s">' % entity.eid)
for tab in tabs:
- w(u'<div id="as-%s">' % tab)
+ w(u'<div>')
if entity:
self.lazyview(tab, eid=entity.eid)
else:
self.lazyview(tab, static=True)
w(u'</div>')
+ w(u'</div>')
# call the set_tab() JS function *after* each tab is generated
# because the callback binding needs to be done before
self.req.html_headers.add_onload(u"""
- jQuery('#entity-tabs-%(eeid)s > ul').tabs( { selected: %(tabindex)s });
- set_tab('%(vid)s', '%(cookiename)s');
- """ % {'tabindex' : tabs.index(active_tab),
- 'vid' : active_tab,
- 'eeid' : (entity and entity.eid or uid),
- 'cookiename' : self.cookie_name})
+ jQuery(function() {
+ jQuery("#tabs-%(eeid)s").tabs("#panes-%(eeid)s > div", {initialIndex: %(tabindex)s});
+ set_tab('%(vid)s', '%(cookiename)s');
+ });""" % {'eeid' : entity.eid,
+ 'vid' : active_tab,
+ 'cookiename' : self.cookie_name,
+ 'tabindex' : tabs.index(active_tab)})
class EntityRelationView(EntityView):
--- a/web/views/treeview.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/treeview.py Thu Jul 02 10:35:03 2009 +0200
@@ -26,7 +26,7 @@
def call(self, subvid=None, treeid=None, initial_load=True):
if subvid is None:
- subvid = self.req.form.pop('subvid', 'oneline') # consume it
+ subvid = self.req.form.pop('treesubvid', 'oneline') # consume it
if treeid is None:
treeid = self.req.form.pop('treeid', None)
if treeid is None:
@@ -117,7 +117,7 @@
pageid=self.req.pageid,
treeid=treeid,
fname='view',
- subvid=vid))
+ treesubvid=vid))
divclasses = ['hitarea']
if is_open:
liclasses.append('collapsable')
--- a/web/views/urlpublishing.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/urlpublishing.py Thu Jul 02 10:35:03 2009 +0200
@@ -239,7 +239,7 @@
continue
else:
try:
- action = self.vreg.select(actions, req, rset)
+ action = self.vreg.select_best(actions, req, rset=rset)
except RegistryException:
raise PathDontMatch()
else:
--- a/web/views/workflow.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/workflow.py Thu Jul 02 10:35:03 2009 +0200
@@ -51,10 +51,9 @@
transition = self.req.eid_rset(self.req.form['treid']).get_entity(0, 0)
dest = transition.destination()
_ = self.req._
- form = self.vreg.select_object('forms', 'changestate', self.req,
- self.rset, row=row, col=col,
- entity=entity,
- redirect_path=self.redirectpath(entity))
+ form = self.vreg.select('forms', 'changestate', self.req, rset=self.rset,
+ row=row, col=col, entity=entity,
+ redirect_path=self.redirectpath(entity))
self.w(form.error_message())
self.w(u'<h4>%s %s</h4>\n' % (_(transition.name),
entity.view('oneline')))
--- a/web/views/xmlrss.py Thu Jul 02 10:30:44 2009 +0200
+++ b/web/views/xmlrss.py Thu Jul 02 10:35:03 2009 +0200
@@ -13,11 +13,9 @@
from logilab.mtconverter import xml_escape
from cubicweb.selectors import non_final_entity, one_line_rset, appobject_selectable
-from cubicweb.view import EntityView, AnyRsetView
-from cubicweb.web.httpcache import MaxAgeHTTPCacheManager
-from cubicweb.web.component import Component
-from cubicweb.web.box import BoxTemplate
+from cubicweb.view import EntityView, AnyRsetView, Component
from cubicweb.common.uilib import simple_sgml_tag
+from cubicweb.web import httpcache, box
# base xml views ##############################################################
@@ -122,10 +120,10 @@
return self.entity(0, 0).rss_feed_url()
-class RSSIconBox(BoxTemplate):
+class RSSIconBox(box.BoxTemplate):
"""just display the RSS icon on uniform result set"""
id = 'rss'
- __select__ = (BoxTemplate.__select__
+ __select__ = (box.BoxTemplate.__select__
& appobject_selectable('components', 'rss_feed_url'))
visible = False
@@ -137,7 +135,8 @@
except KeyError:
self.error('missing RSS_LOGO external resource')
return
- urlgetter = self.vreg.select_component('rss_feed_url', self.req, self.rset)
+ urlgetter = self.vreg.select('components', 'rss_feed_url',
+ self.req, rset=self.rset)
url = urlgetter.feed_url()
self.w(u'<a href="%s"><img src="%s" alt="rss"/></a>\n' % (xml_escape(url), rss))
@@ -147,7 +146,7 @@
title = _('rss')
templatable = False
content_type = 'text/xml'
- http_cache_manager = MaxAgeHTTPCacheManager
+ http_cache_manager = httpcache.MaxAgeHTTPCacheManager
cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
def _open(self):
--- a/wsgi/handler.py Thu Jul 02 10:30:44 2009 +0200
+++ b/wsgi/handler.py Thu Jul 02 10:35:03 2009 +0200
@@ -97,10 +97,7 @@
# assert self.base_url[-1] == '/'
# self.https_url = config['https-url']
# assert not self.https_url or self.https_url[-1] == '/'
- try:
- self.url_rewriter = self.appli.vreg.select_component('urlrewriter')
- except ObjectNotFound:
- self.url_rewriter = None
+ self.url_rewriter = self.appli.vreg.select_object('components', 'urlrewriter')
def _render(self, req):
"""this function performs the actual rendering