19 |
19 |
20 """ |
20 """ |
21 __docformat__ = "restructuredtext en" |
21 __docformat__ = "restructuredtext en" |
22 _ = unicode |
22 _ = unicode |
23 |
23 |
|
24 from warnings import warn |
|
25 |
24 from logilab.mtconverter import xml_escape |
26 from logilab.mtconverter import xml_escape |
25 |
27 |
26 from cubicweb.interfaces import IBreadCrumbs |
28 #from cubicweb.interfaces import IBreadCrumbs |
27 from cubicweb.selectors import (one_line_rset, implements, one_etype_rset, |
29 from cubicweb.selectors import (implements, one_line_rset, adaptable, |
28 multi_lines_rset, any_rset) |
30 one_etype_rset, multi_lines_rset, any_rset) |
29 from cubicweb.view import EntityView, Component |
31 from cubicweb.view import EntityView, Component, EntityAdapter |
30 # don't use AnyEntity since this may cause bug with isinstance() due to reloading |
32 # don't use AnyEntity since this may cause bug with isinstance() due to reloading |
31 from cubicweb.entity import Entity |
33 from cubicweb.entity import Entity |
32 from cubicweb import tags, uilib |
34 from cubicweb import tags, uilib |
33 |
35 |
34 |
36 |
|
37 # ease bw compat |
|
38 def ibreadcrumb_adapter(entity): |
|
39 if hasattr(entity, 'breadcrumbs'): |
|
40 warn('[3.9] breadcrumbs() method is deprecated, define a custom ' |
|
41 'IBreadCrumbsAdapter for %s instead' % entity.__class__, |
|
42 DeprecationWarning) |
|
43 return entity |
|
44 return entity.cw_adapt_to('IBreadCrumbs') |
|
45 |
|
46 |
|
47 class IBreadCrumbsAdapter(EntityAdapter): |
|
48 """adapters for entities which can be"located" on some path to display in |
|
49 the web ui |
|
50 """ |
|
51 __regid__ = 'IBreadCrumbs' |
|
52 __select__ = implements('Any', accept_none=False) |
|
53 |
|
54 def parent_entity(self): |
|
55 if hasattr(self.entity, 'parent'): |
|
56 warn('[3.9] parent() method is deprecated, define a ' |
|
57 'custom IBreadCrumbsAdapter/ITreeAdapter for %s instead' |
|
58 % self.entity.__class__, DeprecationWarning) |
|
59 return self.entity.parent() |
|
60 itree = self.entity.cw_adapt_to('ITree') |
|
61 if itree is not None: |
|
62 return itree.parent() |
|
63 return None |
|
64 |
|
65 def breadcrumbs(self, view=None, recurs=False): |
|
66 """return a list containing some: |
|
67 |
|
68 * tuple (url, label) |
|
69 * entity |
|
70 * simple label string |
|
71 |
|
72 defining path from a root to the current view |
|
73 |
|
74 the main view is given as argument so breadcrumbs may vary according |
|
75 to displayed view (may be None). When recursing on a parent entity, |
|
76 the `recurs` argument should be set to True. |
|
77 """ |
|
78 path = [self.entity] |
|
79 parent = self.parent_entity() |
|
80 if parent is not None: |
|
81 adapter = ibreadcrumb_adapter(self.entity) |
|
82 path = adapter.breadcrumbs(view, True) + [self.entity] |
|
83 if not recurs: |
|
84 if view is None: |
|
85 if 'vtitle' in self._cw.form: |
|
86 # embeding for instance |
|
87 path.append( self._cw.form['vtitle'] ) |
|
88 elif view.__regid__ != 'primary' and hasattr(view, 'title'): |
|
89 path.append( self._cw._(view.title) ) |
|
90 return path |
|
91 |
|
92 |
35 class BreadCrumbEntityVComponent(Component): |
93 class BreadCrumbEntityVComponent(Component): |
36 __regid__ = 'breadcrumbs' |
94 __regid__ = 'breadcrumbs' |
37 __select__ = one_line_rset() & implements(IBreadCrumbs, accept_none=False) |
95 __select__ = one_line_rset() & adaptable('IBreadCrumbs') |
38 |
96 |
39 cw_property_defs = { |
97 cw_property_defs = { |
40 _('visible'): dict(type='Boolean', default=True, |
98 _('visible'): dict(type='Boolean', default=True, |
41 help=_('display the component or not')), |
99 help=_('display the component or not')), |
42 } |
100 } |
45 separator = u' > ' |
103 separator = u' > ' |
46 link_template = u'<a href="%s">%s</a>' |
104 link_template = u'<a href="%s">%s</a>' |
47 |
105 |
48 def call(self, view=None, first_separator=True): |
106 def call(self, view=None, first_separator=True): |
49 entity = self.cw_rset.get_entity(0, 0) |
107 entity = self.cw_rset.get_entity(0, 0) |
50 path = entity.breadcrumbs(view) |
108 adapter = ibreadcrumb_adapter(entity) |
|
109 path = adapter.breadcrumbs(view) |
51 if path: |
110 if path: |
52 self.open_breadcrumbs() |
111 self.open_breadcrumbs() |
53 if first_separator: |
112 if first_separator: |
54 self.w(self.separator) |
113 self.w(self.separator) |
55 self.render_breadcrumbs(entity, path) |
114 self.render_breadcrumbs(entity, path) |
71 for i, parent in enumerate(path): |
130 for i, parent in enumerate(path): |
72 self.w(self.separator) |
131 self.w(self.separator) |
73 self.w(u"\n") |
132 self.w(u"\n") |
74 self.wpath_part(parent, contextentity, i == len(path) - 1) |
133 self.wpath_part(parent, contextentity, i == len(path) - 1) |
75 |
134 |
76 def wpath_part(self, part, contextentity, last=False): |
135 def wpath_part(self, part, contextentity, last=False): # XXX deprecates last argument? |
77 if isinstance(part, Entity): |
136 if isinstance(part, Entity): |
78 self.w(part.view('breadcrumbs')) |
137 self.w(part.view('breadcrumbs')) |
79 elif isinstance(part, tuple): |
138 elif isinstance(part, tuple): |
80 url, title = part |
139 url, title = part |
81 textsize = self._cw.property_value('navigation.short-line-size') |
140 textsize = self._cw.property_value('navigation.short-line-size') |
86 self.w(uilib.cut(unicode(part), textsize)) |
145 self.w(uilib.cut(unicode(part), textsize)) |
87 |
146 |
88 |
147 |
89 class BreadCrumbETypeVComponent(BreadCrumbEntityVComponent): |
148 class BreadCrumbETypeVComponent(BreadCrumbEntityVComponent): |
90 __select__ = multi_lines_rset() & one_etype_rset() & \ |
149 __select__ = multi_lines_rset() & one_etype_rset() & \ |
91 implements(IBreadCrumbs, accept_none=False) |
150 adaptable('IBreadCrumbs') |
92 |
151 |
93 def render_breadcrumbs(self, contextentity, path): |
152 def render_breadcrumbs(self, contextentity, path): |
94 # XXX hack: only display etype name or first non entity path part |
153 # XXX hack: only display etype name or first non entity path part |
95 root = path.pop(0) |
154 root = path.pop(0) |
96 if isinstance(root, Entity): |
155 if isinstance(root, Entity): |