Commit e145605f authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

If it's installed, configure relation widget for display of concepts entities

Code adapted and backported from the SEDA cube.

Closes #14170765
parent f64f72f6ba31
from yams.buildobjs import RelationDefinition
from yams.buildobjs import RelationDefinition, EntityType
from cubicweb.schema import RQLConstraint
class inlined_match(RelationDefinition):
......@@ -6,3 +8,23 @@ class inlined_match(RelationDefinition):
object = ('Concept', 'ExternalUri')
cardinality = '?*'
inlined = True
class scheme_relation_type(RelationDefinition):
subject = 'ConceptScheme'
object = 'CWRType'
cardinality = '**'
class Language(EntityType):
u""""""
class language_to(RelationDefinition):
subject = 'Language'
object = 'Concept'
cardinality = '?*'
inlined = True
constraints = [RQLConstraint('O in_scheme CS, CS scheme_relation_type CR, '
'CR name "language_to"')]
......@@ -107,6 +107,30 @@ class ViewsTC(testlib.CubicWebTC):
self._test_skos_view('list.rdf', 2)
class RelationWidgetTC(testlib.CubicWebTC):
"""Functional test case about the relation widget."""
def test_linkable_rset(self):
with self.admin_access.repo_cnx() as cnx:
lang = cnx.create_entity('Language')
cnx.commit()
with self.admin_access.web_request() as req:
lang = req.entity_from_eid(lang.eid)
req.form = {'relation': 'language_to:Concept:subject'}
view = self.vreg['views'].select('search_related_entities', req,
rset=lang.as_rset())
self.failIf(view.linkable_rset())
with self.admin_access.repo_cnx() as cnx:
scheme = cnx.create_entity('ConceptScheme', title=u'languages')
scheme.add_concept(label=u'fr')
cnx.commit()
with self.admin_access.web_request() as req:
req.form = {'relation': 'language_to:Concept:subject'}
view = self.vreg['views'].select('search_related_entities', req,
rset=lang.as_rset())
self.assertEqual(len(view.linkable_rset()), 1)
if __name__ == '__main__':
from unittest import main
main()
# copyright 2015-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program 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.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
from cubicweb import tags
from cubicweb.predicates import is_instance
try:
from cubes.relationwidget import views as rwdg
except ImportError:
pass
else:
class SearchForRelatedConceptsView(rwdg.SearchForRelatedEntitiesView):
"""Specializes relation widget to link to concepts which are expected to be constrained by
an RQL expression on the edited relation definition.
It will attempt to select the best suited language for display an return properly
prefetched/ordered concepts. It's also expected that all concepts will provide a preferred
label for the selected language (among those defined in the scheme).
"""
__select__ = (rwdg.SearchForRelatedEntitiesView.__select__
& rwdg.edited_relation(tetype='Concept'))
has_creation_form = False
def linkable_rset(self):
"""Return rset of entities to be displayed as possible values for the
edited relation. You may want to override this.
"""
baserql, args = self.constrained_rql()
# detect language first
languages = set(lang for lang, in self._cw.execute(
'DISTINCT Any OLC WHERE ' + baserql + ', O preferred_label OL, '
'OL language_code OLC', args))
for lang in (self._cw.lang, 'en', 'sed-2'):
if lang in languages:
break
else:
if not languages:
return self._cw.empty_rset()
lang = next(iter(languages))
# now build the query to prefetch/sort on the preferred label in the proper language
args['lang'] = lang
return self._cw.execute(
'DISTINCT Any O,OL,OLL ORDERBY OLL WHERE ' + baserql + ', O preferred_label OL, '
'OL label OLL, OL language_code %(lang)s', args)
def constrained_rql(self):
constraints = self.schema_rdef.constraints
assert len(constraints) == 1
baserql = constraints[0].expression
return baserql, {}
@property
def schema_rdef(self):
rtype, tetype, role = self.rdef
entity = self.compute_entity()
return entity.e_schema.rdef(rtype, role, tetype)
@staticmethod
def pref_label_label(concept):
return concept.cw_rset[concept.cw_row][2]
@staticmethod
def pref_label_column(w, concept):
w(tags.a(SearchForRelatedConceptsView.pref_label_label(concept),
href=concept.absolute_url()))
class SelectConceptEntitiesTableView(rwdg.SelectEntitiesTableView):
"""Table view of the selectable entities in the relation widget
Selection of columns (and respective renderer) can be overridden by
updating `columns` and `column_renderers` class attributes.
"""
__select__ = (rwdg.SelectEntitiesTableView.__select__ & is_instance('Concept'))
column_renderers = rwdg.SelectEntitiesTableView.column_renderers.copy()
# speed-up things by considering rset shape from ContainedSearchForRelatedEntitiesView
column_renderers['entity'] = rwdg.SelectMainEntityColRenderer(
sortfunc=SearchForRelatedConceptsView.pref_label_label,
renderfunc=SearchForRelatedConceptsView.pref_label_column)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment