web/views/startup.py
changeset 6961 686c59dfc401
parent 6931 0af44a38fe41
child 6962 220e32f058be
equal deleted inserted replaced
6960:822f2530570d 6961:686c59dfc401
     1 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     3 #
     3 #
     4 # This file is part of CubicWeb.
     4 # This file is part of CubicWeb.
     5 #
     5 #
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    14 # details.
    14 # details.
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """Set of HTML startup views. A startup view is global, e.g. doesn't
    18 """Set of HTML startup views. A startup view is global, e.g. doesn't apply to a
    19 apply to a result set.
    19 result set.
    20 """
    20 """
    21 
    21 
    22 __docformat__ = "restructuredtext en"
    22 __docformat__ = "restructuredtext en"
    23 _ = unicode
    23 _ = unicode
    24 
    24 
    25 from logilab.common.textutils import unormalize
    25 from logilab.common.textutils import unormalize
       
    26 from logilab.common.deprecation import deprecated
    26 from logilab.mtconverter import xml_escape
    27 from logilab.mtconverter import xml_escape
    27 
    28 
    28 from cubicweb.view import StartupView
    29 from cubicweb.view import StartupView
    29 from cubicweb.selectors import match_user_groups, is_instance
    30 from cubicweb.selectors import match_user_groups, is_instance
    30 from cubicweb.schema import display_name
    31 from cubicweb.schema import display_name
    33 class ManageView(StartupView):
    34 class ManageView(StartupView):
    34     __regid__ = 'manage'
    35     __regid__ = 'manage'
    35     title = _('manage')
    36     title = _('manage')
    36     http_cache_manager = httpcache.EtagHTTPCacheManager
    37     http_cache_manager = httpcache.EtagHTTPCacheManager
    37     add_etype_links = ()
    38     add_etype_links = ()
    38 
    39     skip_startup_views = set( ('index', 'manage', 'schema', 'owl', 'changelog',
    39     def display_folders(self):
    40                                'systempropertiesform', 'propertiesform',
    40         return False
    41                                'cw.user-management',
       
    42                                'siteinfo', 'info', 'registry', 'gc',
       
    43                                'tree') )
    41 
    44 
    42     def call(self, **kwargs):
    45     def call(self, **kwargs):
    43         """The default view representing the instance's management"""
    46         """The default view representing the instance's management"""
    44         self._cw.add_css('cubicweb.manageview.css')
    47         self._cw.add_css('cubicweb.manageview.css')
    45         self.w(u'<h1>%s</h1>' % self._cw.property_value('ui.site-title'))
    48         self.w(u'<h1>%s</h1>' % self._cw.property_value('ui.site-title'))
    46         if not self.display_folders():
    49         self.entities()
    47             self._main_index()
    50         self.manage_actions()
    48         else:
    51         self.startup_views()
    49             self.w(u'<table><tr>\n')
       
    50             self.w(u'<td style="width:40%">')
       
    51             self._main_index()
       
    52             self.w(u'</td><td style="width:60%">')
       
    53             self.folders()
       
    54             self.w(u'</td>')
       
    55             self.w(u'</tr></table>\n')
       
    56 
    52 
    57     def _main_index(self):
    53     def manage_actions(self):
    58         req = self._cw
    54         allactions = self._cw.vreg['actions'].possible_actions(self._cw)
    59         manager = req.user.matching_groups('managers')
    55         if allactions.get('manage'):
    60         if not manager and 'Card' in self._cw.vreg.schema:
       
    61             rset = self._cw.execute('Card X WHERE X wikiid "index"')
       
    62         else:
       
    63             rset = None
       
    64         if rset:
       
    65             self.wview('inlined', rset, row=0)
       
    66         else:
       
    67             self.entities()
       
    68             self.w(u'<div class="hr">&#160;</div>')
    56             self.w(u'<div class="hr">&#160;</div>')
    69             self.startup_views()
    57             self.w(u'<h2>%s</h2>\n' % self._cw._('Manage'))
    70         if manager and 'Card' in self._cw.vreg.schema:
    58             self.w(u'<ul class="manageActions">')
    71             self.w(u'<div class="hr">&#160;</div>')
    59             for action in allactions['manage']:
    72             if rset:
       
    73                 href = rset.get_entity(0, 0).absolute_url(vid='edition')
       
    74                 label = self._cw._('edit the index page')
       
    75             else:
       
    76                 href = req.build_url('view', vid='creation', etype='Card', wikiid='index')
       
    77                 label = self._cw._('create an index page')
       
    78             self.w(u'<br/><a href="%s">%s</a>\n' % (xml_escape(href), label))
       
    79 
       
    80     def folders(self):
       
    81         self.w(u'<h2>%s</h2>\n' % self._cw._('Browse by category'))
       
    82         self._cw.vreg['views'].select('tree', self._cw).render(w=self.w, maxlevel=1)
       
    83 
       
    84     def create_links(self):
       
    85         self.w(u'<ul class="createLink">')
       
    86         for etype in self.add_etype_links:
       
    87             eschema = self._cw.vreg.schema.eschema(etype)
       
    88             if eschema.has_perm(self._cw, 'add'):
       
    89                 self.w(u'<li><a href="%s">%s</a></li>' % (
    60                 self.w(u'<li><a href="%s">%s</a></li>' % (
    90                         self._cw.build_url('add/%s' % eschema),
    61                     action.url(), self._cw._(action.title)))
    91                         self._cw.__('add a %s' % eschema).capitalize()))
    62             self.w(u'</ul>')
    92         self.w(u'</ul>')
       
    93 
    63 
    94     def startup_views(self):
    64     def startup_views(self):
    95         self.w(u'<h2>%s</h2>\n' % self._cw._('Startup views'))
       
    96         self.startupviews_table()
       
    97 
       
    98     def startupviews_table(self):
       
    99         views = self._cw.vreg['views'].possible_views(self._cw, None)
    65         views = self._cw.vreg['views'].possible_views(self._cw, None)
   100         if not views:
    66         if not views:
   101             return
    67             return
       
    68         self.w(u'<div class="hr">&#160;</div>')
       
    69         self.w(u'<h2>%s</h2>\n' % self._cw._('Startup views'))
   102         self.w(u'<ul class="startup">')
    70         self.w(u'<ul class="startup">')
   103         for v in sorted(views, key=lambda x: self._cw._(x.title)):
    71         for v in sorted(views, key=lambda x: self._cw._(x.title)):
   104             if v.category != 'startupview' or v.__regid__ in ('index', 'tree', 'manage'):
    72             if v.category != 'startupview' or v.__regid__ in self.skip_startup_views:
   105                 continue
    73                 continue
   106             self.w('<li><a href="%s">%s</a></li>' % (
    74             self.w('<li><a href="%s">%s</a></li>' % (
   107                 xml_escape(v.url()), xml_escape(self._cw._(v.title).capitalize())))
    75                 xml_escape(v.url()), xml_escape(self._cw._(v.title).capitalize())))
   108         self.w(u'</ul>')
    76         self.w(u'</ul>')
   109 
    77 
   110     def entities(self):
    78     def entities(self):
   111         schema = self._cw.vreg.schema
    79         schema = self._cw.vreg.schema
       
    80         self.w(u'<div class="hr">&#160;</div>')
   112         self.w(u'<h2>%s</h2>\n' % self._cw._('Browse by entity type'))
    81         self.w(u'<h2>%s</h2>\n' % self._cw._('Browse by entity type'))
   113         manager = self._cw.user.matching_groups('managers')
    82         manager = self._cw.user.matching_groups('managers')
   114         self.w(u'<table class="startup">')
    83         self.w(u'<table class="startup">')
   115         if manager:
       
   116             self.w(u'<tr><th colspan="4">%s</th></tr>\n' % self._cw._('application entities'))
       
   117         self.entity_types_table(eschema for eschema in schema.entities()
    84         self.entity_types_table(eschema for eschema in schema.entities()
   118                                 if uicfg.indexview_etype_section.get(eschema) == 'application')
    85                                 if uicfg.indexview_etype_section.get(eschema) == 'application')
   119         if manager:
       
   120             self.w(u'<tr><th colspan="4">%s</th></tr>\n' % self._cw._('system entities'))
       
   121             self.entity_types_table(eschema for eschema in schema.entities()
       
   122                                 if uicfg.indexview_etype_section.get(eschema) == 'system')
       
   123         self.w(u'</table>')
    86         self.w(u'</table>')
   124 
    87 
   125     def entity_types_table(self, eschemas):
    88     def entity_types_table(self, eschemas):
   126         newline = 0
       
   127         infos = sorted(self.entity_types(eschemas),
    89         infos = sorted(self.entity_types(eschemas),
   128                        key=lambda (l,a,e):unormalize(l))
    90                        key=lambda (l,a,e): unormalize(l))
   129         q, r = divmod(len(infos), 2)
    91         q, r = divmod(len(infos), 2)
   130         if r:
    92         if r:
   131             infos.append( (None, '&#160;', '&#160;') )
    93             infos.append( (None, '&#160;', '&#160;') )
   132         infos = zip(infos[:q+r], infos[q+r:])
    94         infos = zip(infos[:q+r], infos[q+r:])
   133         for (_, etypelink, addlink), (_, etypelink2, addlink2) in infos:
    95         for (_, etypelink, addlink), (_, etypelink2, addlink2) in infos:
   134             self.w(u'<tr>\n')
    96             self.w(u'<tr>\n')
   135             self.w(u'<td class="addcol">%s</td><td>%s</td>\n' % (addlink,  etypelink))
    97             self.w(u'<td class="addcol">%s</td><td>%s</td>\n' % (addlink,  etypelink))
   136             self.w(u'<td class="addcol">%s</td><td>%s</td>\n' % (addlink2, etypelink2))
    98             self.w(u'<td class="addcol">%s</td><td>%s</td>\n' % (addlink2, etypelink2))
   137             self.w(u'</tr>\n')
    99             self.w(u'</tr>\n')
   138 
   100 
   139 
       
   140     def entity_types(self, eschemas):
   101     def entity_types(self, eschemas):
   141         """return a list of formatted links to get a list of entities of
   102         """return an iterator on formatted links to get a list of entities of
   142         a each entity's types
   103         each entity types
   143         """
   104         """
   144         req = self._cw
   105         req = self._cw
   145         for eschema in eschemas:
   106         for eschema in eschemas:
   146             if eschema.final or not eschema.may_have_permission('read', req):
   107             if eschema.final or not eschema.may_have_permission('read', req):
   147                 continue
   108                 continue
   155             url = self._cw.build_url(etype)
   116             url = self._cw.build_url(etype)
   156             etypelink = u'&#160;<a href="%s">%s</a> (%d)' % (
   117             etypelink = u'&#160;<a href="%s">%s</a> (%d)' % (
   157                 xml_escape(url), label, nb)
   118                 xml_escape(url), label, nb)
   158             if eschema.has_perm(req, 'add'):
   119             if eschema.has_perm(req, 'add'):
   159                 yield (label, etypelink, self.add_entity_link(etype))
   120                 yield (label, etypelink, self.add_entity_link(etype))
       
   121             else:
       
   122                 yield (label, etypelink, u'')
       
   123 
       
   124     def create_links(self):
       
   125         self.w(u'<ul class="createLink">')
       
   126         for etype in self.add_etype_links:
       
   127             eschema = self.schema.eschema(etype)
       
   128             if eschema.has_perm(self._cw, 'add'):
       
   129                 self.w(u'<li><a href="%s">%s</a></li>' % (
       
   130                         self._cw.build_url('add/%s' % eschema),
       
   131                         self._cw.__('add a %s' % eschema).capitalize()))
       
   132         self.w(u'</ul>')
   160 
   133 
   161     def add_entity_link(self, etype):
   134     def add_entity_link(self, etype):
   162         """creates a [+] link for adding an entity"""
   135         """creates a [+] link for adding an entity"""
   163         url = self._cw.vreg["etypes"].etype_class(etype).cw_create_url(self._cw)
   136         url = self._cw.vreg["etypes"].etype_class(etype).cw_create_url(self._cw)
   164         return u'[<a href="%s" title="%s">+</a>]' % (
   137         return u'[<a href="%s" title="%s">+</a>]' % (
   165             xml_escape(url), self._cw.__('add a %s' % etype))
   138             xml_escape(url), self._cw.__('add a %s' % etype))
   166 
   139 
       
   140     @deprecated('[3.11] display_folders method is deprecated, backport it if needed')
       
   141     def display_folders(self):
       
   142         return False
       
   143 
       
   144     @deprecated('[3.11] folders method is deprecated, backport it if needed')
       
   145     def folders(self):
       
   146         self.w(u'<h2>%s</h2>\n' % self._cw._('Browse by category'))
       
   147         self._cw.vreg['views'].select('tree', self._cw).render(w=self.w, maxlevel=1)
       
   148 
   167 
   149 
   168 class IndexView(ManageView):
   150 class IndexView(ManageView):
   169     __regid__ = 'index'
   151     __regid__ = 'index'
   170     title = _('view_index')
   152     title = _('view_index')
   171 
   153 
       
   154     @deprecated('[3.11] display_folders method is deprecated, backport it if needed')
   172     def display_folders(self):
   155     def display_folders(self):
   173         return 'Folder' in self._cw.vreg.schema and self._cw.execute('Any COUNT(X) WHERE X is Folder')[0][0]
   156         return 'Folder' in self._cw.vreg.schema and self._cw.execute('Any COUNT(X) WHERE X is Folder')[0][0]
   174 
   157