diff -r 058bb3dc685f -r 0b59724cb3f2 web/views/ibreadcrumbs.py --- a/web/views/ibreadcrumbs.py Mon Jan 04 18:40:30 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. -# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr -# -# This file is part of CubicWeb. -# -# CubicWeb is free software: you can redistribute it and/or modify it under the -# terms of the GNU Lesser General Public License as published by the Free -# Software Foundation, either version 2.1 of the License, or (at your option) -# any later version. -# -# CubicWeb is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License along -# with CubicWeb. If not, see . -"""breadcrumbs components definition for CubicWeb web client""" - -__docformat__ = "restructuredtext en" -from cubicweb import _ - -from warnings import warn - -from six import text_type - -from logilab.mtconverter import xml_escape - -from cubicweb import tags, uilib -from cubicweb.entity import Entity -from cubicweb.predicates import (is_instance, one_line_rset, adaptable, - one_etype_rset, multi_lines_rset, any_rset, - match_form_params) -from cubicweb.view import EntityView, EntityAdapter -from cubicweb.web.views import basecomponents -# don't use AnyEntity since this may cause bug with isinstance() due to reloading - - - -class IBreadCrumbsAdapter(EntityAdapter): - """adapters for entities which can be"located" on some path to display in - the web ui - """ - __regid__ = 'IBreadCrumbs' - __select__ = is_instance('Any', accept_none=False) - - def parent_entity(self): - itree = self.entity.cw_adapt_to('ITree') - if itree is not None: - return itree.parent() - return None - - def breadcrumbs(self, view=None, recurs=None): - """return a list containing some: - - * tuple (url, label) - * entity - * simple label string - - defining path from a root to the current view - - the main view is given as argument so breadcrumbs may vary according to - displayed view (may be None). When recursing on a parent entity, the - `recurs` argument should be a set of already traversed nodes (infinite - loop safety belt). - """ - parent = self.parent_entity() - if parent is not None: - if recurs: - _recurs = recurs - else: - _recurs = set() - if _recurs and parent.eid in _recurs: - self.error('cycle in breadcrumbs for entity %s' % self.entity) - return [] - _recurs.add(parent.eid) - adapter = parent.cw_adapt_to('IBreadCrumbs') - path = adapter.breadcrumbs(view, _recurs) + [self.entity] - else: - path = [self.entity] - if not recurs: - if view is None: - if 'vtitle' in self._cw.form: - # embeding for instance - path.append( self._cw.form['vtitle'] ) - elif view.__regid__ != 'primary' and hasattr(view, 'title'): - path.append( self._cw._(view.title) ) - return path - - -class BreadCrumbEntityVComponent(basecomponents.HeaderComponent): - __regid__ = 'breadcrumbs' - __select__ = (basecomponents.HeaderComponent.__select__ - & one_line_rset() & adaptable('IBreadCrumbs')) - order = basecomponents.ApplicationName.order + 1 - context = basecomponents.ApplicationName.context - separator = u' > ' - link_template = u'%s' - first_separator = True - - # XXX support kwargs for compat with other components which gets the view as - # argument - def render(self, w, **kwargs): - try: - entity = self.cw_extra_kwargs['entity'] - except KeyError: - entity = self.cw_rset.get_entity(0, 0) - adapter = entity.cw_adapt_to('IBreadCrumbs') - view = self.cw_extra_kwargs.get('view') - path = adapter.breadcrumbs(view) - if path: - self.open_breadcrumbs(w) - self.render_breadcrumbs(w, entity, path) - self.close_breadcrumbs(w) - - def open_breadcrumbs(self, w): - w(u'') - if self.first_separator: - w(self.separator) - - def close_breadcrumbs(self, w): - w(u'') - - def render_breadcrumbs(self, w, contextentity, path): - root = path.pop(0) - if isinstance(root, Entity): - w(self.link_template % (self._cw.build_url(root.__regid__), - root.dc_type('plural'))) - w(self.separator) - self.wpath_part(w, root, contextentity, not path) - for i, parent in enumerate(path): - w(self.separator) - w(u"\n") - self.wpath_part(w, parent, contextentity, i == len(path) - 1) - - def wpath_part(self, w, part, contextentity, last=False): # XXX deprecates last argument? - if isinstance(part, Entity): - w(part.view('breadcrumbs')) - elif isinstance(part, tuple): - url, title = part - textsize = self._cw.property_value('navigation.short-line-size') - w(self.link_template % ( - xml_escape(url), xml_escape(uilib.cut(title, textsize)))) - else: - textsize = self._cw.property_value('navigation.short-line-size') - w(xml_escape(uilib.cut(text_type(part), textsize))) - - -class BreadCrumbETypeVComponent(BreadCrumbEntityVComponent): - __select__ = (basecomponents.HeaderComponent.__select__ - & multi_lines_rset() & one_etype_rset() - & adaptable('IBreadCrumbs')) - - def render_breadcrumbs(self, w, contextentity, path): - # XXX hack: only display etype name or first non entity path part - root = path.pop(0) - if isinstance(root, Entity): - w(u'%s' % (self._cw.build_url(root.__regid__), - root.dc_type('plural'))) - else: - self.wpath_part(w, root, contextentity, not path) - - -class BreadCrumbAnyRSetVComponent(BreadCrumbEntityVComponent): - __select__ = basecomponents.HeaderComponent.__select__ & any_rset() - - # XXX support kwargs for compat with other components which gets the view as - # argument - def render(self, w, **kwargs): - self.open_breadcrumbs(w) - w(self._cw._('search')) - self.close_breadcrumbs(w) - - -class BreadCrumbLinkToVComponent(BreadCrumbEntityVComponent): - __select__ = basecomponents.HeaderComponent.__select__ & match_form_params('__linkto') - - def render(self, w, **kwargs): - eid = self._cw.list_form_param('__linkto')[0].split(':')[1] - entity = self._cw.entity_from_eid(eid) - ecmp = self._cw.vreg[self.__registry__].select( - self.__regid__, self._cw, entity=entity, **kwargs) - ecmp.render(w, **kwargs) - - -class BreadCrumbView(EntityView): - __regid__ = 'breadcrumbs' - - def cell_call(self, row, col, **kwargs): - entity = self.cw_rset.get_entity(row, col) - desc = uilib.cut(entity.dc_description(), 50) - # NOTE remember camember: tags.a autoescapes - self.w(tags.a(entity.view('breadcrumbtext'), - href=entity.absolute_url(), title=desc)) - - -class BreadCrumbTextView(EntityView): - __regid__ = 'breadcrumbtext' - - def cell_call(self, row, col, **kwargs): - entity = self.cw_rset.get_entity(row, col) - textsize = self._cw.property_value('navigation.short-line-size') - self.w(uilib.cut(entity.dc_title(), textsize))