--- a/src/pyams_thesaurus/widget/__init__.py Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-import json
-import re
-
-# import interfaces
-from pyams_form.interfaces.form import IFormLayer
-from pyams_thesaurus.interfaces.term import IThesaurusTerm
-from pyams_thesaurus.interfaces.thesaurus import IThesaurus
-from pyams_thesaurus.schema import IThesaurusTermField, IThesaurusTermsListField
-from pyams_thesaurus.widget.interfaces import IThesaurusTermWidget, IThesaurusTermsListWidget
-from z3c.form.interfaces import IDataConverter, IFieldWidget
-
-# import packages
-from pyams_form.widget import widgettemplate_config
-from pyams_utils.adapter import adapter_config
-from pyams_utils.registry import get_utility, query_utility
-from pyams_utils.traversing import get_parent
-from z3c.form.browser.widget import HTMLInputWidget
-from z3c.form.converter import BaseDataConverter
-from z3c.form.widget import Widget, FieldWidget
-from zope.interface import implementer_only
-from zope.schema.fieldproperty import FieldProperty
-
-
-SYNONYM = re.compile('(.*)\ \[\ .*\ \]')
-
-
-#
-# Term widget
-#
-
-@adapter_config(context=(IThesaurusTermField, IThesaurusTermWidget), provides=IDataConverter)
-class ThesaurusTermDataConverter(BaseDataConverter):
- """Thesaurus term data converter"""
-
- def toWidgetValue(self, value):
- # Widget expects term label or caption
- if value is self.field.missing_value:
- return ''
- if IThesaurusTerm.providedBy(self.widget.context):
- return value.label
- else:
- return value.title
-
- def toFieldValue(self, value):
- # Field expects thesaurus term instance
- if not value:
- return self.field.missing_value
- match = SYNONYM.match(value)
- if match:
- value = match.groups()[0]
- thesaurus_name = self.widget.thesaurus_name or self.field.thesaurus_name
- if thesaurus_name:
- thesaurus = get_utility(IThesaurus, name=thesaurus_name)
- else:
- thesaurus = get_parent(self.widget.context, IThesaurus)
- if thesaurus is None:
- thesaurus = query_utility(IThesaurus, name=thesaurus_name)
- if thesaurus is None:
- return None
- else:
- return thesaurus.terms.get(value)
-
-
-@widgettemplate_config(mode='input', template='templates/term-input.pt', layer=IFormLayer)
-@widgettemplate_config(mode='display', template='templates/term-display.pt', layer=IFormLayer)
-@implementer_only(IThesaurusTermWidget)
-class ThesaurusTermWidget(HTMLInputWidget, Widget):
- """Thesaurus term widget"""
-
- thesaurus_name = FieldProperty(IThesaurusTermWidget['thesaurus_name'])
- extract_name = FieldProperty(IThesaurusTermWidget['extract_name'])
-
- @property
- def query_params(self):
- return json.dumps({'thesaurus_name': self.thesaurus_name,
- 'extract_name': self.extract_name})
-
- @property
- def values_map(self):
- return json.dumps({self.value: self.value})
-
-
-@adapter_config(context=(IThesaurusTermField, IFormLayer), provides=IFieldWidget)
-def ThesaurusTermFieldWidget(field, request):
- """Thesaurus term field widget factory"""
- return FieldWidget(field, ThesaurusTermWidget(request))
-
-
-#
-# Terms list widget
-#
-
-@adapter_config(context=(IThesaurusTermsListField, IThesaurusTermsListWidget), provides=IDataConverter)
-class ThesaurusTermsListDataConverter(BaseDataConverter):
- """Thesaurus terms list data converter"""
-
- def __init__(self, field, widget):
- super(ThesaurusTermsListDataConverter, self).__init__(field, widget)
-
- def toWidgetValue(self, value):
- # Widget expects a list of thesaurus terms labels or captions
- if value is self.field.missing_value:
- return []
- if IThesaurusTerm.providedBy(self.widget.context):
- return [term.label for term in value]
- else:
- return [term.title for term in value]
-
- def toFieldValue(self, value):
- # Field expects a list of thesaurus terms
- if not value:
- return self.field.missing_value
- thesaurus_name = self.widget.thesaurus_name or self.field.thesaurus_name
- if thesaurus_name:
- thesaurus = get_utility(IThesaurus, name=thesaurus_name)
- else:
- thesaurus = get_parent(self.widget.context, IThesaurus)
- if thesaurus is None:
- thesaurus = query_utility(IThesaurus, name=thesaurus_name)
- if thesaurus is None:
- return None
- if isinstance(value, str):
- value = value.split('|')
- for idx, val in enumerate(value):
- match = SYNONYM.match(val)
- if match:
- value[idx] = match.groups()[0]
- terms = thesaurus.terms
- return [terms.get(term) for term in value]
-
-
-@widgettemplate_config(mode='input', template='templates/terms-list-input.pt', layer=IFormLayer)
-@widgettemplate_config(mode='display', template='templates/terms-list-display.pt', layer=IFormLayer)
-@implementer_only(IThesaurusTermsListWidget)
-class ThesaurusTermsListWidget(HTMLInputWidget, Widget):
- """Thesaurus terms list widget"""
-
- thesaurus_name = FieldProperty(IThesaurusTermsListWidget['thesaurus_name'])
- extract_name = FieldProperty(IThesaurusTermsListWidget['extract_name'])
-
- @property
- def query_params(self):
- return json.dumps({'thesaurus_name': self.thesaurus_name,
- 'extract_name': self.extract_name})
-
- @property
- def values_map(self):
- result = {}
- [result.update({value: value}) for value in (self.value or ())]
- return json.dumps(result)
-
-
-@adapter_config(context=(IThesaurusTermsListField, IFormLayer), provides=IFieldWidget)
-def ThesaurusTermsListFieldWidget(field, request):
- """Thesaurus terms list field widget factory"""
- return FieldWidget(field, ThesaurusTermsListWidget(request))
-
-
-@widgettemplate_config(mode='input', template='templates/terms-tree-input.pt', layer=IFormLayer)
-class ThesaurusTermsTreeWidget(ThesaurusTermsListWidget):
- """Thesaurus terms tree widget"""
-
- @property
- def top_terms(self):
- thesaurus = query_utility(IThesaurus, name=self.thesaurus_name)
- if thesaurus is not None:
- return sorted(thesaurus.get_top_terms(extract=self.extract_name),
- key=lambda x: x.label)
- else:
- return ()
-
- def get_subterms(self, term):
- for subterm in term.specifics:
- if (not self.extract_name) or (self.extract_name in subterm.extracts):
- yield subterm
- for another in self.get_subterms(subterm):
- yield another
-
-
-def ThesaurusTermsTreeFieldWidget(field, request):
- """Thesaurus terms tree field widget factory"""
- return FieldWidget(field, ThesaurusTermsTreeWidget(request))
-
-
-#
-# Terms list widget with selector
-#
-
-@widgettemplate_config(mode='input', template='templates/terms-list-selector-input.pt', layer=IFormLayer)
-class ThesaurusTermsListSelectorWidget(ThesaurusTermsListWidget):
- """Thesaurus terms list widget with selector"""
-
-
-def ThesaurusTermsListSelectorFieldWidget(field, request):
- """Thesaurus terms list field widget with selector factory"""
- return FieldWidget(field, ThesaurusTermsListSelectorWidget(request))
--- a/src/pyams_thesaurus/widget/interfaces.py Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from z3c.form.interfaces import IWidget
-
-# import packages
-from zope.schema import TextLine
-
-
-class IThesaurusTermWidget(IWidget):
- """Single term widget"""
-
- thesaurus_name = TextLine(title="Thesaurus name",
- required=False)
-
- extract_name = TextLine(title="Extract name",
- required=False)
-
-
-class IThesaurusTermsListWidget(IWidget):
- """Terms list widget"""
-
- thesaurus_name = TextLine(title="Thesaurus name",
- required=False,
- default='')
-
- extract_name = TextLine(title="Extract name",
- required=False,
- default='')
--- a/src/pyams_thesaurus/widget/templates/term-display.pt Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-<input type="hidden" autocomplete="off" readonly
- tal:attributes="id view/id;
- name view/name;
- class string:select2 ${view/klass};
- style view/style;
- title view/title;
- value view/value | nothing;
- lang view/lang;
- onclick view/onclick;
- ondblclick view/ondblclick;
- onmousedown view/onmousedown;
- onmouseup view/onmouseup;
- onmouseover view/onmouseover;
- onmousemove view/onmousemove;
- onmouseout view/onmouseout;
- onkeypress view/onkeypress;
- onkeydown view/onkeydown;
- onkeyup view/onkeyup;
- disabled view/disabled;
- tabindex view/tabindex;
- onfocus view/onfocus;
- onblur view/onblur;
- onchange view/onchange;
- accesskey view/accesskey;
- onselect view/onselect;" />
--- a/src/pyams_thesaurus/widget/templates/term-input.pt Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-<label class="input bordered with-icon"
- tal:omit-tag="view/required" i18n:domain="pyams_thesaurus">
- <i class="icon-append fa fa-trash-o text-primary hint opaque"
- title="Clear selected value" i18n:attributes="title"
- tal:omit-tag="view/required"
- data-ams-hint-gravity="se"
- data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
- tal:attributes="data-ams-select2-target view/name"></i>
- <div class="select2-parent"
- tal:omit-tag="view/required">
- <input type="hidden" autocomplete="off"
- data-ams-select2-minimum-input-length="2"
- data-ams-select2-allow-clear="true"
- data-ams-select2-multiple="true"
- data-ams-select2-maximum-selection-size="1"
- data-ams-select2-query-method="findTerms"
- data-ams-select2-method-target="/api/thesaurus/json"
- tal:attributes="id view/id;
- name view/name;
- class string:select2 ${view/klass};
- style view/style;
- title view/title;
- value view/value | nothing;
- lang view/lang;
- onclick view/onclick;
- ondblclick view/ondblclick;
- onmousedown view/onmousedown;
- onmouseup view/onmouseup;
- onmouseover view/onmouseover;
- onmousemove view/onmousemove;
- onmouseout view/onmouseout;
- onkeypress view/onkeypress;
- onkeydown view/onkeydown;
- onkeyup view/onkeyup;
- disabled view/disabled;
- tabindex view/tabindex;
- onfocus view/onfocus;
- onblur view/onblur;
- onchange view/onchange;
- readonly view/readonly;
- accesskey view/accesskey;
- onselect view/onselect;
- data-ams-select2-values view/values_map;
- data-ams-select2-query-params view/query_params;" />
- </div>
-</label>
--- a/src/pyams_thesaurus/widget/templates/terms-list-display.pt Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-<input type="hidden" autocomplete="off" readonly
- data-ams-select2-multiple="true"
- data-ams-select2-separator="|"
- tal:attributes="id view/id;
- name view/name;
- class string:select2 ${view/klass};
- style view/style;
- title view/title;
- value python:'|'.join(view.value);
- lang view/lang;
- onclick view/onclick;
- ondblclick view/ondblclick;
- onmousedown view/onmousedown;
- onmouseup view/onmouseup;
- onmouseover view/onmouseover;
- onmousemove view/onmousemove;
- onmouseout view/onmouseout;
- onkeypress view/onkeypress;
- onkeydown view/onkeydown;
- onkeyup view/onkeyup;
- disabled view/disabled;
- tabindex view/tabindex;
- onfocus view/onfocus;
- onblur view/onblur;
- onchange view/onchange;
- accesskey view/accesskey;
- onselect view/onselect;
- data-ams-select2-values view/values_map;" />
--- a/src/pyams_thesaurus/widget/templates/terms-list-input.pt Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-<label class="input bordered with-icon"
- tal:omit-tag="view/required" i18n:domain="pyams_thesaurus">
- <i class="icon-append fa fa-trash-o text-primary hint opaque"
- title="Clear selected values" i18n:attributes="title"
- tal:omit-tag="view/required"
- data-ams-hint-gravity="se"
- data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
- tal:attributes="data-ams-select2-target view/name"></i>
- <div class="select2-parent"
- tal:omit-tag="view/required">
- <input type="hidden" autocomplete="off"
- data-ams-select2-minimum-input-length="2"
- data-ams-select2-allow-clear="true"
- data-ams-select2-multiple="true"
- data-ams-select2-separator="|"
- data-ams-select2-query-method="findTerms"
- data-ams-select2-method-target="/api/thesaurus/json"
- tal:attributes="id view/id;
- name view/name;
- class string:select2 ${view/klass};
- style view/style;
- title view/title;
- value python:'|'.join(view.value or ());
- lang view/lang;
- onclick view/onclick;
- ondblclick view/ondblclick;
- onmousedown view/onmousedown;
- onmouseup view/onmouseup;
- onmouseover view/onmouseover;
- onmousemove view/onmousemove;
- onmouseout view/onmouseout;
- onkeypress view/onkeypress;
- onkeydown view/onkeydown;
- onkeyup view/onkeyup;
- disabled view/disabled;
- tabindex view/tabindex;
- onfocus view/onfocus;
- onblur view/onblur;
- onchange view/onchange;
- readonly view/readonly;
- accesskey view/accesskey;
- onselect view/onselect;
- data-ams-select2-values view/values_map;
- data-ams-select2-query-params view/query_params;" />
- </div>
-</label>
--- a/src/pyams_thesaurus/widget/templates/terms-list-selector-input.pt Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-<label class="input bordered with-icons" i18n:domain="pyams_thesaurus">
- <i class="icon-append fa fa-trash-o text-primary hint opaque"
- title="Clear selected values" i18n:attributes="title"
- tal:omit-tag="view/required"
- data-ams-hint-gravity="se"
- data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
- tal:attributes="data-ams-select2-target view/name"></i>
- <i class="icon-append icon-append-2 fa fa-th-list text-primary hint opaque"
- title="Show terms selector" i18n:attributes="title"
- data-ams-url="MyAMS.helpers.select2ClearSelection"
- data-toggle="modal"
- tal:attributes="data-ams-select2-target view/name"></i>
- <div class="select2-parent">
- <input type="hidden" autocomplete="off"
- data-ams-select2-minimum-input-length="2"
- data-ams-select2-allow-clear="true"
- data-ams-select2-multiple="true"
- data-ams-select2-separator="|"
- data-ams-select2-query-method="findTerms"
- data-ams-select2-method-target="/api/thesaurus/json"
- tal:attributes="id view/id;
- name view/name;
- class string:select2 ${view/klass};
- style view/style;
- title view/title;
- value python:'|'.join(view.value or ());
- lang view/lang;
- onclick view/onclick;
- ondblclick view/ondblclick;
- onmousedown view/onmousedown;
- onmouseup view/onmouseup;
- onmouseover view/onmouseover;
- onmousemove view/onmousemove;
- onmouseout view/onmouseout;
- onkeypress view/onkeypress;
- onkeydown view/onkeydown;
- onkeyup view/onkeyup;
- disabled view/disabled;
- tabindex view/tabindex;
- onfocus view/onfocus;
- onblur view/onblur;
- onchange view/onchange;
- readonly view/readonly;
- accesskey view/accesskey;
- onselect view/onselect;
- data-ams-select2-values view/values_map;
- data-ams-select2-query-params view/query_params;" />
- </div>
-</label>
--- a/src/pyams_thesaurus/widget/templates/terms-tree-input.pt Wed Jul 11 10:18:34 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-<tal:loop repeat="term view/top_terms">
- <div class="col col-xs-6 col-sm-4 col-md-4 col-lg-3">
- <div class="ams-widget" data-ams-widget-toggle-button="false"
- tal:define="index python:repeat['term'].index()"
- tal:attributes="id string:them_${index}">
- <header class="no-margin">
- <h2 tal:content="term/label"></h2>
- </header>
- <div class="widget-body no-padding viewport-y viewport-200 viewport-x-none"
- style="height: 200px; width: calc(100% - 2px);">
- <tal:loop repeat="subterm python:view.get_subterms(term)">
- <div tal:define="padding python:(subterm.level - 1) * 20"
- tal:attributes="style string:padding-left: ${padding}px;; line-height: 1em;;">
- <label class="checkbox"
- tal:define="published python:subterm.status == 'published'"
- tal:omit-tag="not:published">
- <input type="checkbox" name="form.widgets.themes:list"
- tal:condition="published"
- tal:attributes="id string:term_${subterm/label};
- name string:${view/name}:list;
- value subterm/label;
- checked python:subterm.label in view.value" />
- <i></i>
- <div tal:attributes="class python:'' if published else 'bold margin-top-5'"
- tal:content="subterm/label"></div>
- </label>
- </div>
- </tal:loop>
- </div>
- </div>
- </div>
-</tal:loop>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/__init__.py Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,212 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import json
+import re
+
+# import interfaces
+from pyams_form.interfaces.form import IFormLayer
+from pyams_thesaurus.interfaces.term import IThesaurusTerm
+from pyams_thesaurus.interfaces.thesaurus import IThesaurus
+from pyams_thesaurus.schema import IThesaurusTermField, IThesaurusTermsListField
+from pyams_thesaurus.zmi.widget.interfaces import IThesaurusTermWidget, IThesaurusTermsListWidget
+from z3c.form.interfaces import IDataConverter, IFieldWidget
+
+# import packages
+from pyams_form.widget import widgettemplate_config
+from pyams_utils.adapter import adapter_config
+from pyams_utils.registry import get_utility, query_utility
+from pyams_utils.traversing import get_parent
+from z3c.form.browser.widget import HTMLInputWidget
+from z3c.form.converter import BaseDataConverter
+from z3c.form.widget import Widget, FieldWidget
+from zope.interface import implementer_only
+from zope.schema.fieldproperty import FieldProperty
+
+
+SYNONYM = re.compile('(.*)\ \[\ .*\ \]')
+
+
+#
+# Term widget
+#
+
+@adapter_config(context=(IThesaurusTermField, IThesaurusTermWidget), provides=IDataConverter)
+class ThesaurusTermDataConverter(BaseDataConverter):
+ """Thesaurus term data converter"""
+
+ def toWidgetValue(self, value):
+ # Widget expects term label or caption
+ if value is self.field.missing_value:
+ return ''
+ if IThesaurusTerm.providedBy(self.widget.context):
+ return value.label
+ else:
+ return value.title
+
+ def toFieldValue(self, value):
+ # Field expects thesaurus term instance
+ if not value:
+ return self.field.missing_value
+ match = SYNONYM.match(value)
+ if match:
+ value = match.groups()[0]
+ thesaurus_name = self.widget.thesaurus_name or self.field.thesaurus_name
+ if thesaurus_name:
+ thesaurus = get_utility(IThesaurus, name=thesaurus_name)
+ else:
+ thesaurus = get_parent(self.widget.context, IThesaurus)
+ if thesaurus is None:
+ thesaurus = query_utility(IThesaurus, name=thesaurus_name)
+ if thesaurus is None:
+ return None
+ else:
+ return thesaurus.terms.get(value)
+
+
+@widgettemplate_config(mode='input', template='templates/term-input.pt', layer=IFormLayer)
+@widgettemplate_config(mode='display', template='templates/term-display.pt', layer=IFormLayer)
+@implementer_only(IThesaurusTermWidget)
+class ThesaurusTermWidget(HTMLInputWidget, Widget):
+ """Thesaurus term widget"""
+
+ thesaurus_name = FieldProperty(IThesaurusTermWidget['thesaurus_name'])
+ extract_name = FieldProperty(IThesaurusTermWidget['extract_name'])
+
+ @property
+ def query_params(self):
+ return json.dumps({'thesaurus_name': self.thesaurus_name,
+ 'extract_name': self.extract_name})
+
+ @property
+ def values_map(self):
+ return json.dumps({self.value: self.value})
+
+
+@adapter_config(context=(IThesaurusTermField, IFormLayer), provides=IFieldWidget)
+def ThesaurusTermFieldWidget(field, request):
+ """Thesaurus term field widget factory"""
+ return FieldWidget(field, ThesaurusTermWidget(request))
+
+
+#
+# Terms list widget
+#
+
+@adapter_config(context=(IThesaurusTermsListField, IThesaurusTermsListWidget), provides=IDataConverter)
+class ThesaurusTermsListDataConverter(BaseDataConverter):
+ """Thesaurus terms list data converter"""
+
+ def __init__(self, field, widget):
+ super(ThesaurusTermsListDataConverter, self).__init__(field, widget)
+
+ def toWidgetValue(self, value):
+ # Widget expects a list of thesaurus terms labels or captions
+ if value is self.field.missing_value:
+ return []
+ if IThesaurusTerm.providedBy(self.widget.context):
+ return [term.label for term in value]
+ else:
+ return [term.title for term in value]
+
+ def toFieldValue(self, value):
+ # Field expects a list of thesaurus terms
+ if not value:
+ return self.field.missing_value
+ thesaurus_name = self.widget.thesaurus_name or self.field.thesaurus_name
+ if thesaurus_name:
+ thesaurus = get_utility(IThesaurus, name=thesaurus_name)
+ else:
+ thesaurus = get_parent(self.widget.context, IThesaurus)
+ if thesaurus is None:
+ thesaurus = query_utility(IThesaurus, name=thesaurus_name)
+ if thesaurus is None:
+ return None
+ if isinstance(value, str):
+ value = value.split('|')
+ for idx, val in enumerate(value):
+ match = SYNONYM.match(val)
+ if match:
+ value[idx] = match.groups()[0]
+ terms = thesaurus.terms
+ return [terms.get(term) for term in value]
+
+
+@widgettemplate_config(mode='input', template='templates/terms-list-input.pt', layer=IFormLayer)
+@widgettemplate_config(mode='display', template='templates/terms-list-display.pt', layer=IFormLayer)
+@implementer_only(IThesaurusTermsListWidget)
+class ThesaurusTermsListWidget(HTMLInputWidget, Widget):
+ """Thesaurus terms list widget"""
+
+ thesaurus_name = FieldProperty(IThesaurusTermsListWidget['thesaurus_name'])
+ extract_name = FieldProperty(IThesaurusTermsListWidget['extract_name'])
+
+ @property
+ def query_params(self):
+ return json.dumps({'thesaurus_name': self.thesaurus_name,
+ 'extract_name': self.extract_name})
+
+ @property
+ def values_map(self):
+ result = {}
+ [result.update({value: value}) for value in (self.value or ())]
+ return json.dumps(result)
+
+
+@adapter_config(context=(IThesaurusTermsListField, IFormLayer), provides=IFieldWidget)
+def ThesaurusTermsListFieldWidget(field, request):
+ """Thesaurus terms list field widget factory"""
+ return FieldWidget(field, ThesaurusTermsListWidget(request))
+
+
+@widgettemplate_config(mode='input', template='templates/terms-tree-input.pt', layer=IFormLayer)
+class ThesaurusTermsTreeWidget(ThesaurusTermsListWidget):
+ """Thesaurus terms tree widget"""
+
+ @property
+ def top_terms(self):
+ thesaurus = query_utility(IThesaurus, name=self.thesaurus_name)
+ if thesaurus is not None:
+ return sorted(thesaurus.get_top_terms(extract=self.extract_name),
+ key=lambda x: x.label)
+ else:
+ return ()
+
+ def get_subterms(self, term):
+ for subterm in term.specifics:
+ if (not self.extract_name) or (self.extract_name in subterm.extracts):
+ yield subterm
+ for another in self.get_subterms(subterm):
+ yield another
+
+
+def ThesaurusTermsTreeFieldWidget(field, request):
+ """Thesaurus terms tree field widget factory"""
+ return FieldWidget(field, ThesaurusTermsTreeWidget(request))
+
+
+#
+# Terms list widget with selector
+#
+
+@widgettemplate_config(mode='input', template='templates/terms-list-selector-input.pt', layer=IFormLayer)
+class ThesaurusTermsListSelectorWidget(ThesaurusTermsListWidget):
+ """Thesaurus terms list widget with selector"""
+
+
+def ThesaurusTermsListSelectorFieldWidget(field, request):
+ """Thesaurus terms list field widget with selector factory"""
+ return FieldWidget(field, ThesaurusTermsListSelectorWidget(request))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/interfaces.py Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from z3c.form.interfaces import IWidget
+
+# import packages
+from zope.schema import TextLine
+
+
+class IThesaurusTermWidget(IWidget):
+ """Single term widget"""
+
+ thesaurus_name = TextLine(title="Thesaurus name",
+ required=False)
+
+ extract_name = TextLine(title="Extract name",
+ required=False)
+
+
+class IThesaurusTermsListWidget(IWidget):
+ """Terms list widget"""
+
+ thesaurus_name = TextLine(title="Thesaurus name",
+ required=False,
+ default='')
+
+ extract_name = TextLine(title="Extract name",
+ required=False,
+ default='')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/templates/term-display.pt Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,25 @@
+<input type="hidden" autocomplete="off" readonly
+ tal:attributes="id view/id;
+ name view/name;
+ class string:select2 ${view/klass};
+ style view/style;
+ title view/title;
+ value view/value | nothing;
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ accesskey view/accesskey;
+ onselect view/onselect;" />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/templates/term-input.pt Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,46 @@
+<label class="input bordered with-icon"
+ tal:omit-tag="view/required" i18n:domain="pyams_thesaurus">
+ <i class="icon-append fa fa-trash-o text-primary hint opaque"
+ title="Clear selected value" i18n:attributes="title"
+ tal:omit-tag="view/required"
+ data-ams-hint-gravity="se"
+ data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
+ tal:attributes="data-ams-select2-target view/name"></i>
+ <div class="select2-parent"
+ tal:omit-tag="view/required">
+ <input type="hidden" autocomplete="off"
+ data-ams-select2-minimum-input-length="2"
+ data-ams-select2-allow-clear="true"
+ data-ams-select2-multiple="true"
+ data-ams-select2-maximum-selection-size="1"
+ data-ams-select2-query-method="findTerms"
+ data-ams-select2-method-target="/api/thesaurus/json"
+ tal:attributes="id view/id;
+ name view/name;
+ class string:select2 ${view/klass};
+ style view/style;
+ title view/title;
+ value view/value | nothing;
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ readonly view/readonly;
+ accesskey view/accesskey;
+ onselect view/onselect;
+ data-ams-select2-values view/values_map;
+ data-ams-select2-query-params view/query_params;" />
+ </div>
+</label>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/templates/terms-list-display.pt Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,28 @@
+<input type="hidden" autocomplete="off" readonly
+ data-ams-select2-multiple="true"
+ data-ams-select2-separator="|"
+ tal:attributes="id view/id;
+ name view/name;
+ class string:select2 ${view/klass};
+ style view/style;
+ title view/title;
+ value python:'|'.join(view.value);
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ accesskey view/accesskey;
+ onselect view/onselect;
+ data-ams-select2-values view/values_map;" />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/templates/terms-list-input.pt Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,46 @@
+<label class="input bordered with-icon"
+ tal:omit-tag="view/required" i18n:domain="pyams_thesaurus">
+ <i class="icon-append fa fa-trash-o text-primary hint opaque"
+ title="Clear selected values" i18n:attributes="title"
+ tal:omit-tag="view/required"
+ data-ams-hint-gravity="se"
+ data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
+ tal:attributes="data-ams-select2-target view/name"></i>
+ <div class="select2-parent"
+ tal:omit-tag="view/required">
+ <input type="hidden" autocomplete="off"
+ data-ams-select2-minimum-input-length="2"
+ data-ams-select2-allow-clear="true"
+ data-ams-select2-multiple="true"
+ data-ams-select2-separator="|"
+ data-ams-select2-query-method="findTerms"
+ data-ams-select2-method-target="/api/thesaurus/json"
+ tal:attributes="id view/id;
+ name view/name;
+ class string:select2 ${view/klass};
+ style view/style;
+ title view/title;
+ value python:'|'.join(view.value or ());
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ readonly view/readonly;
+ accesskey view/accesskey;
+ onselect view/onselect;
+ data-ams-select2-values view/values_map;
+ data-ams-select2-query-params view/query_params;" />
+ </div>
+</label>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/templates/terms-list-selector-input.pt Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,49 @@
+<label class="input bordered with-icons" i18n:domain="pyams_thesaurus">
+ <i class="icon-append fa fa-trash-o text-primary hint opaque"
+ title="Clear selected values" i18n:attributes="title"
+ tal:omit-tag="view/required"
+ data-ams-hint-gravity="se"
+ data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
+ tal:attributes="data-ams-select2-target view/name"></i>
+ <i class="icon-append icon-append-2 fa fa-th-list text-primary hint opaque"
+ title="Show terms selector" i18n:attributes="title"
+ data-ams-url="MyAMS.helpers.select2ClearSelection"
+ data-toggle="modal"
+ tal:attributes="data-ams-select2-target view/name"></i>
+ <div class="select2-parent">
+ <input type="hidden" autocomplete="off"
+ data-ams-select2-minimum-input-length="2"
+ data-ams-select2-allow-clear="true"
+ data-ams-select2-multiple="true"
+ data-ams-select2-separator="|"
+ data-ams-select2-query-method="findTerms"
+ data-ams-select2-method-target="/api/thesaurus/json"
+ tal:attributes="id view/id;
+ name view/name;
+ class string:select2 ${view/klass};
+ style view/style;
+ title view/title;
+ value python:'|'.join(view.value or ());
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ readonly view/readonly;
+ accesskey view/accesskey;
+ onselect view/onselect;
+ data-ams-select2-values view/values_map;
+ data-ams-select2-query-params view/query_params;" />
+ </div>
+</label>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_thesaurus/zmi/widget/templates/terms-tree-input.pt Wed Jul 11 10:18:57 2018 +0200
@@ -0,0 +1,32 @@
+<tal:loop repeat="term view/top_terms">
+ <div class="col col-xs-6 col-sm-4 col-md-3 col-lg-3">
+ <div class="ams-widget" data-ams-widget-toggle-button="false"
+ tal:define="index python:repeat['term'].index()"
+ tal:attributes="id string:them_${index}">
+ <header class="no-margin">
+ <h2 tal:content="term/label"></h2>
+ </header>
+ <div class="widget-body no-padding viewport-y viewport-200 viewport-x-none"
+ style="height: 200px; width: calc(100% - 2px);">
+ <tal:loop repeat="subterm python:view.get_subterms(term)">
+ <div tal:define="padding python:(subterm.level - 1) * 20"
+ tal:attributes="style string:padding-left: ${padding}px;; line-height: 1em;;">
+ <label class="checkbox"
+ tal:define="published python:subterm.status == 'published'"
+ tal:omit-tag="not:published">
+ <input type="checkbox" name="form.widgets.themes:list"
+ tal:condition="published"
+ tal:attributes="id string:term_${subterm/label};
+ name string:${view/name}:list;
+ value subterm/label;
+ checked python:subterm.label in view.value" />
+ <i></i>
+ <div tal:attributes="class python:'' if published else 'bold margin-top-5'"
+ tal:content="subterm/label"></div>
+ </label>
+ </div>
+ </tal:loop>
+ </div>
+ </div>
+ </div>
+</tal:loop>