UI for adding either 'simple keyword' (a string) or 'concept keyword' (a reference to a concept)
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 20 Jan 2017 14:45:50 +0100
changeset 2315 17b947d38a25
parent 2314 4286fd72c879
child 2316 f54a06d45f49
UI for adding either 'simple keyword' (a string) or 'concept keyword' (a reference to a concept) This is done using a 'keyword_type' parameters at creation time, then detecting if the keyword has a reference or not. In the case of simple keyword, only display cardinality and keyword's content (the string). For concept, hide keyword's content but force creation of a reference. Reference's cardinality may be hidden, though a bit of work will be needed to generate '1' cardinality on profile export. Related to #16070921
i18n/en.po
i18n/fr.po
views/archiveunit.py
--- a/i18n/en.po	Fri Jan 20 10:39:21 2017 +0100
+++ b/i18n/en.po	Fri Jan 20 14:45:50 2017 +0100
@@ -4659,6 +4659,9 @@
 msgid "juridictional"
 msgstr ""
 
+msgid "keyword concept"
+msgstr ""
+
 #, python-brace-format
 msgid "keyword reference: {0}"
 msgstr ""
@@ -4667,6 +4670,9 @@
 msgid "keyword scheme: {0}"
 msgstr ""
 
+msgid "keyword simple"
+msgstr ""
+
 #, python-brace-format
 msgid "keyword type: {0}"
 msgstr ""
--- a/i18n/fr.po	Fri Jan 20 10:39:21 2017 +0100
+++ b/i18n/fr.po	Fri Jan 20 14:45:50 2017 +0100
@@ -4678,13 +4678,19 @@
 msgid "juridictional"
 msgstr ""
 
+msgid "keyword concept"
+msgstr "mot-clé de référence"
+
 #, python-brace-format
 msgid "keyword reference: {0}"
-msgstr "référence : {0}"
+msgstr "mot-clé de référence : {0}"
 
 #, python-brace-format
 msgid "keyword scheme: {0}"
-msgstr "vocabulaire : {0}"
+msgstr "mot-clé du vocabulaire {0}"
+
+msgid "keyword simple"
+msgstr "mot-clé simple"
 
 #, python-brace-format
 msgid "keyword type: {0}"
--- a/views/archiveunit.py	Fri Jan 20 10:39:21 2017 +0100
+++ b/views/archiveunit.py	Fri Jan 20 14:45:50 2017 +0100
@@ -24,7 +24,7 @@
 from cubicweb import tags, _
 from cubicweb.predicates import is_instance
 from cubicweb.view import EntityView
-from cubicweb.web.views import uicfg, baseviews, tabs
+from cubicweb.web.views import autoform, baseviews, tabs, uicfg
 
 from cubes.compound import views as compound
 from cubes.relationwidget import views as rwdg
@@ -85,6 +85,21 @@
 
 
 @objectify_predicate
+def is_simple_keyword(cls, req, rset=None, entity=None, **kwargs):
+    """Return 1 if a keyword_type value is specified in kwargs or in form parameters, and its value is
+    'simple_keyword', or if given entity is not linked to a keyword reference.
+    """
+    try:
+        # first check for unit_type specified in form params
+        unit_type = req.form['keyword_type']
+        return int(unit_type == 'simple_keyword')
+    except KeyError:
+        if not entity.reverse_seda_keyword_reference_from:
+            return 1
+        return 0
+
+
+@objectify_predicate
 def is_typed_reference(cls, req, entity=None, **kwargs):
     """Return positive score for content's typed data object references (IsPartOf, VersionOf, etc.), not
     those starting directly from archive unit.
@@ -532,12 +547,25 @@
         ('seda_keyword', 'object', 'SEDAKeyword'),
         ('seda_tag', 'object', 'SEDATag'),
     ]
+    keyword_custom_arguments = [
+        ('keyword_type', 'simple_keyword', _('keyword simple')),
+        ('keyword_type', 'concept_keyword', _('keyword concept')),
+    ]
 
     _('creating SEDAKeyword (SEDAKeyword seda_keyword '
       'SEDASeqAltArchiveUnitArchiveUnitRefIdManagement %(linkto)s)')
     _('creating SEDATag (SEDATag seda_tag '
       'SEDASeqAltArchiveUnitArchiveUnitRefIdManagement %(linkto)s)')
 
+    def display_add_button(self, entity):
+        urlparams = self.url_params(entity)
+        links = add_links_with_custom_arguments(entity, 'seda_keyword', 'object', urlparams,
+                                                self.keyword_custom_arguments)
+        rtype_roles = [(rtype, role) for rtype, role, _ in self.rtype_role_targets
+                       if rtype != 'seda_keyword']
+        links += viewlib.add_links_from_rtype_roles(entity, rtype_roles, urlparams)
+        viewlib.display_add_button(self.w, links, entity._cw.__('add'))
+
 
 class SimplifiedArchiveUnitContentIndexationView(ContentIndexationView):
 
@@ -551,20 +579,6 @@
     __select__ = viewlib.ListItemContentView.__select__ & is_instance('SEDAKeyword')
 
     def entity_call(self, entity):
-        if entity.seda_keyword_content[0].keyword_content:
-            content = entity.seda_keyword_content[0].keyword_content
-        else:
-            content = self._cw._('<no value specified>')
-        msg = xml_escape(self._cw._('keyword: {0}').format(content))
-        self.w(u'<span class="value">{0} {1}</span>'.format(msg, entity.view('seda.xsdmeta')))
-        if entity.reverse_seda_keyword_type_from:
-            kwt = entity.reverse_seda_keyword_type_from[0]
-            if kwt.seda_keyword_type_to:
-                kwt_value = kwt.seda_keyword_type_to[0].label()
-            else:
-                kwt_value = self._cw._('<no type specified>')
-            msg = xml_escape(self._cw._('keyword type: {0}').format(kwt_value))
-            self.w(u'<br/><span>{0} {1}</span>'.format(msg, kwt.view('seda.xsdmeta')))
         if entity.reverse_seda_keyword_reference_from:
             kwr = entity.reverse_seda_keyword_reference_from[0]
             if kwr.concept:
@@ -575,7 +589,22 @@
                 msg = xml_escape(self._cw._('keyword scheme: {0}')).format(kwr_value)
             else:
                 msg = xml_escape(self._cw._('<no reference specified>'))
-            self.w(u'<br/><span>{0} {1}</span>'.format(msg, kwr.view('seda.xsdmeta')))
+        else:
+            if entity.keyword_content:
+                content = entity.keyword_content
+            else:
+                content = self._cw._('<no value specified>')
+            msg = xml_escape(self._cw._('keyword: {0}').format(content))
+        self.w(u'<span class="value">{0} {1}</span>'.format(msg, entity.view('seda.xsdmeta')))
+
+        if entity.reverse_seda_keyword_type_from:
+            kwt = entity.reverse_seda_keyword_type_from[0]
+            if kwt.seda_keyword_type_to:
+                kwt_value = kwt.seda_keyword_type_to[0].label()
+            else:
+                kwt_value = self._cw._('<no type specified>')
+            msg = xml_escape(self._cw._('keyword type: {0}').format(kwt_value))
+            self.w(u'<br/><span>{0} {1}</span>'.format(msg, kwt.view('seda.xsdmeta')))
 
 
 afs.tag_subject_of(('SEDAKeywordReference', 'seda_keyword_reference_to_scheme', '*'),
@@ -588,6 +617,28 @@
                                                'seda_keyword_reference_to_scheme',
                                                'seda_keyword_reference_to'])
 
+# add rule in afs for 'complex keyword'
+afs.tag_attribute(('SEDAKeyword', 'keyword_content'), 'main', 'hidden')
+afs.tag_attribute(('SEDAKeywordReference', 'user_cardinality'), 'main', 'hidden')
+# custom afs to handle 'simple keyword'
+kw_simple_afs = copy_rtag(afs, __name__,
+                          is_instance('SEDAKeyword') & is_simple_keyword())
+kw_simple_afs.tag_attribute(('SEDAKeyword', 'keyword_content'), 'main', 'attributes')
+kw_simple_afs.tag_object_of(
+    ('*', 'seda_keyword_reference_from', 'SEDAKeyword'),
+    'main', 'hidden')
+# but one ordering is enough to rule them all
+affk.set_fields_order('SEDAKeyword', ['keyword_content', ('seda_keyword_reference_from', 'object')])
+
+
+class ComplexKeywordAutomaticEntityForm(autoform.AutomaticEntityForm):
+    __select__ = (is_instance('SEDAKeyword') & ~is_simple_keyword())
+
+    def should_display_inline_creation_form(self, rschema, existing, card):
+        # 1. force creation of one appraisal/access rule
+        if rschema == 'seda_keyword_reference_from':
+            return True
+
 
 # relations tab ################################################################