[manage view] cleanup manage view and user menu
* drop code that shouldn't be there (e.g. folders handling)
* add a section displaying site management actions, some of them
were initially in the user's drop down menu, which now only have
a 'manage' link with regards to management actions
* stop displaying 'system' and 'schema' entities by default, only
'application' entities
* put 'gc', 'registry' and 'info' views as tabs of a generic
'server information' view
--- a/web/views/actions.py Wed Feb 09 18:06:24 2011 +0100
+++ b/web/views/actions.py Wed Feb 09 18:06:25 2011 +0100
@@ -391,6 +391,7 @@
__regid__ = 'siteconfig'
title = _('site configuration')
order = 10
+ category = 'manage'
class ManageAction(ManagersAction):
--- a/web/views/cwuser.py Wed Feb 09 18:06:24 2011 +0100
+++ b/web/views/cwuser.py Wed Feb 09 18:06:25 2011 +0100
@@ -164,14 +164,14 @@
class ManageUsersAction(actions.ManagersAction):
__regid__ = 'cwuser' # see rewrite rule /cwuser
- title = _('users management')
+ title = _('users and groups')
category = 'manage'
class CWUserManagementView(StartupView):
__regid__ = 'cw.user-management'
rql = ('Any U, F, S, U, L ORDERBY L WHERE U is CWUser, U login L, U firstname F, U surname S')
- title = _('users management')
+ title = _('users and groups management')
def call(self, **kwargs):
self.w('<h1>%s</h1>' % self._cw._(self.title))
--- a/web/views/debug.py Wed Feb 09 18:06:24 2011 +0100
+++ b/web/views/debug.py Wed Feb 09 18:06:25 2011 +0100
@@ -27,7 +27,7 @@
from cubicweb import BadConnectionId
from cubicweb.selectors import none_rset, match_user_groups
from cubicweb.view import StartupView
-from cubicweb.web.views import actions
+from cubicweb.web.views import actions, tabs
def dict_to_html(w, dict):
# XHTML doesn't allow emtpy <ul> nodes
@@ -39,12 +39,24 @@
w(u'</ul>')
-
class SiteInfoAction(actions.ManagersAction):
__regid__ = 'siteinfo'
__select__ = match_user_groups('users','managers')
- title = _('info')
- order = 30
+ title = _('siteinfo')
+ category = 'manage'
+ order = 1000
+
+
+class SiteInfoView(tabs.TabsMixin, StartupView):
+ __regid__ = 'siteinfo'
+ title = _('Site information')
+ tabs = [_('info'), _('registry'), _('gc')]
+ default_tab = 'info'
+
+ def call(self, **kwargs):
+ """The default view representing the instance's management"""
+ self.w(u'<h1>%s</h1>' % self._cw._(self.title))
+ self.render_tabs(self.tabs, self.default_tab)
class ProcessInformationView(StartupView):
@@ -61,7 +73,7 @@
_ = req._
w = self.w
# generic instance information
- w(u'<h1>%s</h1>' % _('Instance'))
+ w(u'<h2>%s</h2>' % _('Instance'))
w(u'<table>')
w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
_('config type'), self._cw.vreg.config.name))
@@ -82,7 +94,7 @@
w(u'</table>')
# repository information
repo = req.vreg.config.repository(None)
- w(u'<h1>%s</h1>' % _('Repository'))
+ w(u'<h2>%s</h2>' % _('Repository'))
w(u'<h3>%s</h3>' % _('resources usage'))
w(u'<table>')
stats = repo.stats()
@@ -107,7 +119,7 @@
else:
w(u'<p>%s</p>' % _('no repository sessions found'))
# web server information
- w(u'<h1>%s</h1>' % _('Web server'))
+ w(u'<h2>%s</h2>' % _('Web server'))
w(u'<table>')
w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
_('base url'), req.base_url()))
@@ -146,7 +158,7 @@
cache_max_age = 0
def call(self, **kwargs):
- self.w(u'<h1>%s</h1>' % self._cw._("Registry's content"))
+ self.w(u'<h2>%s</h2>' % self._cw._("Registry's content"))
keys = sorted(self._cw.vreg)
url = xml_escape(self._cw.url())
self.w(u'<p>%s</p>\n' % ' - '.join('<a href="%s#%s">%s</a>'
@@ -154,7 +166,7 @@
for key in keys:
if key in ('boxes', 'contentnavigation'): # those are bw compat registries
continue
- self.w(u'<h2 id="%s">%s</h2>' % (key, key))
+ self.w(u'<h3 id="%s">%s</h3>' % (key, key))
if self._cw.vreg[key]:
values = sorted(self._cw.vreg[key].iteritems())
self.wview('pyvaltable', pyvalue=[(key, xml_escape(repr(val)))
@@ -186,7 +198,7 @@
lookupclasses += (InternalSession, Session)
except ImportError:
pass # no server part installed
- self.w(u'<h1>%s</h1>' % _('Garbage collection information'))
+ self.w(u'<h2>%s</h2>' % _('Garbage collection information'))
counters, ocounters, garbage = gc_info(lookupclasses,
viewreferrersclasses=())
self.w(u'<h3>%s</h3>' % self._cw._('Looked up classes'))
--- a/web/views/schema.py Wed Feb 09 18:06:24 2011 +0100
+++ b/web/views/schema.py Wed Feb 09 18:06:25 2011 +0100
@@ -690,13 +690,14 @@
__select__ = facet.AttributeFacet.__select__ & is_instance('CWEType', 'CWRType')
rtype = 'final'
+
class ViewSchemaAction(action.Action):
__regid__ = 'schema'
__select__ = yes()
title = _("site schema")
- category = 'siteactions'
order = 30
+ category = 'manage'
def url(self):
return self._cw.build_url(self.__regid__)
--- a/web/views/startup.py Wed Feb 09 18:06:24 2011 +0100
+++ b/web/views/startup.py Wed Feb 09 18:06:25 2011 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -15,14 +15,15 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Set of HTML startup views. A startup view is global, e.g. doesn't
-apply to a result set.
+"""Set of HTML startup views. A startup view is global, e.g. doesn't apply to a
+result set.
"""
__docformat__ = "restructuredtext en"
_ = unicode
from logilab.common.textutils import unormalize
+from logilab.common.deprecation import deprecated
from logilab.mtconverter import xml_escape
from cubicweb.view import StartupView
@@ -35,73 +36,40 @@
title = _('manage')
http_cache_manager = httpcache.EtagHTTPCacheManager
add_etype_links = ()
-
- def display_folders(self):
- return False
+ skip_startup_views = set( ('index', 'manage', 'schema', 'owl', 'changelog',
+ 'systempropertiesform', 'propertiesform',
+ 'cw.user-management',
+ 'siteinfo', 'info', 'registry', 'gc',
+ 'tree') )
def call(self, **kwargs):
"""The default view representing the instance's management"""
self._cw.add_css('cubicweb.manageview.css')
self.w(u'<h1>%s</h1>' % self._cw.property_value('ui.site-title'))
- if not self.display_folders():
- self._main_index()
- else:
- self.w(u'<table><tr>\n')
- self.w(u'<td style="width:40%">')
- self._main_index()
- self.w(u'</td><td style="width:60%">')
- self.folders()
- self.w(u'</td>')
- self.w(u'</tr></table>\n')
+ self.entities()
+ self.manage_actions()
+ self.startup_views()
- def _main_index(self):
- req = self._cw
- manager = req.user.matching_groups('managers')
- if not manager and 'Card' in self._cw.vreg.schema:
- rset = self._cw.execute('Card X WHERE X wikiid "index"')
- else:
- rset = None
- if rset:
- self.wview('inlined', rset, row=0)
- else:
- self.entities()
+ def manage_actions(self):
+ allactions = self._cw.vreg['actions'].possible_actions(self._cw)
+ if allactions.get('manage'):
self.w(u'<div class="hr"> </div>')
- self.startup_views()
- if manager and 'Card' in self._cw.vreg.schema:
- self.w(u'<div class="hr"> </div>')
- if rset:
- href = rset.get_entity(0, 0).absolute_url(vid='edition')
- label = self._cw._('edit the index page')
- else:
- href = req.build_url('view', vid='creation', etype='Card', wikiid='index')
- label = self._cw._('create an index page')
- self.w(u'<br/><a href="%s">%s</a>\n' % (xml_escape(href), label))
-
- def folders(self):
- self.w(u'<h2>%s</h2>\n' % self._cw._('Browse by category'))
- self._cw.vreg['views'].select('tree', self._cw).render(w=self.w, maxlevel=1)
-
- def create_links(self):
- self.w(u'<ul class="createLink">')
- for etype in self.add_etype_links:
- eschema = self._cw.vreg.schema.eschema(etype)
- if eschema.has_perm(self._cw, 'add'):
+ self.w(u'<h2>%s</h2>\n' % self._cw._('Manage'))
+ self.w(u'<ul class="manageActions">')
+ for action in allactions['manage']:
self.w(u'<li><a href="%s">%s</a></li>' % (
- self._cw.build_url('add/%s' % eschema),
- self._cw.__('add a %s' % eschema).capitalize()))
- self.w(u'</ul>')
+ action.url(), self._cw._(action.title)))
+ self.w(u'</ul>')
def startup_views(self):
- self.w(u'<h2>%s</h2>\n' % self._cw._('Startup views'))
- self.startupviews_table()
-
- def startupviews_table(self):
views = self._cw.vreg['views'].possible_views(self._cw, None)
if not views:
return
+ self.w(u'<div class="hr"> </div>')
+ self.w(u'<h2>%s</h2>\n' % self._cw._('Startup views'))
self.w(u'<ul class="startup">')
for v in sorted(views, key=lambda x: self._cw._(x.title)):
- if v.category != 'startupview' or v.__regid__ in ('index', 'tree', 'manage'):
+ if v.category != 'startupview' or v.__regid__ in self.skip_startup_views:
continue
self.w('<li><a href="%s">%s</a></li>' % (
xml_escape(v.url()), xml_escape(self._cw._(v.title).capitalize())))
@@ -109,23 +77,17 @@
def entities(self):
schema = self._cw.vreg.schema
+ self.w(u'<div class="hr"> </div>')
self.w(u'<h2>%s</h2>\n' % self._cw._('Browse by entity type'))
manager = self._cw.user.matching_groups('managers')
self.w(u'<table class="startup">')
- if manager:
- self.w(u'<tr><th colspan="4">%s</th></tr>\n' % self._cw._('application entities'))
self.entity_types_table(eschema for eschema in schema.entities()
if uicfg.indexview_etype_section.get(eschema) == 'application')
- if manager:
- self.w(u'<tr><th colspan="4">%s</th></tr>\n' % self._cw._('system entities'))
- self.entity_types_table(eschema for eschema in schema.entities()
- if uicfg.indexview_etype_section.get(eschema) == 'system')
self.w(u'</table>')
def entity_types_table(self, eschemas):
- newline = 0
infos = sorted(self.entity_types(eschemas),
- key=lambda (l,a,e):unormalize(l))
+ key=lambda (l,a,e): unormalize(l))
q, r = divmod(len(infos), 2)
if r:
infos.append( (None, ' ', ' ') )
@@ -136,10 +98,9 @@
self.w(u'<td class="addcol">%s</td><td>%s</td>\n' % (addlink2, etypelink2))
self.w(u'</tr>\n')
-
def entity_types(self, eschemas):
- """return a list of formatted links to get a list of entities of
- a each entity's types
+ """return an iterator on formatted links to get a list of entities of
+ each entity types
"""
req = self._cw
for eschema in eschemas:
@@ -157,6 +118,18 @@
xml_escape(url), label, nb)
if eschema.has_perm(req, 'add'):
yield (label, etypelink, self.add_entity_link(etype))
+ else:
+ yield (label, etypelink, u'')
+
+ def create_links(self):
+ self.w(u'<ul class="createLink">')
+ for etype in self.add_etype_links:
+ eschema = self.schema.eschema(etype)
+ if eschema.has_perm(self._cw, 'add'):
+ self.w(u'<li><a href="%s">%s</a></li>' % (
+ self._cw.build_url('add/%s' % eschema),
+ self._cw.__('add a %s' % eschema).capitalize()))
+ self.w(u'</ul>')
def add_entity_link(self, etype):
"""creates a [+] link for adding an entity"""
@@ -164,11 +137,21 @@
return u'[<a href="%s" title="%s">+</a>]' % (
xml_escape(url), self._cw.__('add a %s' % etype))
+ @deprecated('[3.11] display_folders method is deprecated, backport it if needed')
+ def display_folders(self):
+ return False
+
+ @deprecated('[3.11] folders method is deprecated, backport it if needed')
+ def folders(self):
+ self.w(u'<h2>%s</h2>\n' % self._cw._('Browse by category'))
+ self._cw.vreg['views'].select('tree', self._cw).render(w=self.w, maxlevel=1)
+
class IndexView(ManageView):
__regid__ = 'index'
title = _('view_index')
+ @deprecated('[3.11] display_folders method is deprecated, backport it if needed')
def display_folders(self):
return 'Folder' in self._cw.vreg.schema and self._cw.execute('Any COUNT(X) WHERE X is Folder')[0][0]
--- a/web/views/urlpublishing.py Wed Feb 09 18:06:24 2011 +0100
+++ b/web/views/urlpublishing.py Wed Feb 09 18:06:25 2011 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
--- a/web/views/urlrewrite.py Wed Feb 09 18:06:24 2011 +0100
+++ b/web/views/urlrewrite.py Wed Feb 09 18:06:25 2011 +0100
@@ -90,7 +90,7 @@
('/index', dict(vid='index')),
('/myprefs', dict(vid='propertiesform')),
('/siteconfig', dict(vid='systempropertiesform')),
- ('/siteinfo', dict(vid='info')),
+ ('/siteinfo', dict(vid='siteinfo')),
('/manage', dict(vid='manage')),
('/notfound', dict(vid='404')),
('/error', dict(vid='error')),