Included chages after moving from intids to simpler implementation
This commit is contained in:
parent
2104bc4c20
commit
7416350c25
|
@ -0,0 +1,19 @@
|
||||||
|
PFWBGED - Notes réunion avec service doc
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
- Définition des termes de l'interface
|
||||||
|
|
||||||
|
Equivalences entre crochet = pas suffisant
|
||||||
|
au moins un intitulé ("employé pour")
|
||||||
|
|
||||||
|
BT = termes génériques
|
||||||
|
RT = voir aussi (termes associés)
|
||||||
|
NT = termes spécifiques
|
||||||
|
|
||||||
|
Employé pour (équivalences) (nobreak, semicolon)
|
||||||
|
|
||||||
|
NA = Note d'application
|
||||||
|
NH = Note historique
|
||||||
|
|
||||||
|
nothing = /néant/
|
||||||
|
|
7
setup.py
7
setup.py
|
@ -17,7 +17,7 @@ long_description = (
|
||||||
|
|
||||||
setup(name='collective.dms.thesaurus',
|
setup(name='collective.dms.thesaurus',
|
||||||
version=version,
|
version=version,
|
||||||
description="Mail content type for document management system",
|
description="Thesaurus based keywords for Plone",
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Environment :: Web Environment",
|
"Environment :: Web Environment",
|
||||||
|
@ -42,8 +42,9 @@ setup(name='collective.dms.thesaurus',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'setuptools',
|
'setuptools',
|
||||||
'plone.app.dexterity',
|
'plone.app.dexterity',
|
||||||
'plone.directives.form',
|
#'plone.directives.form',
|
||||||
'collective.contact.core',
|
#'collective.contact.core',
|
||||||
|
'collective.dms.thesauruswidget',
|
||||||
'five.grok',
|
'five.grok',
|
||||||
],
|
],
|
||||||
extras_require={
|
extras_require={
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
from zope.interface import implements, implementer
|
|
||||||
from zope.component import adapter, getUtility
|
|
||||||
from zope.app.intid.interfaces import IIntIds
|
|
||||||
|
|
||||||
from zc.relation.interfaces import ICatalog
|
|
||||||
|
|
||||||
from z3c.form.interfaces import IFormLayer, IFieldWidget
|
|
||||||
from z3c.form.widget import FieldWidget
|
|
||||||
from z3c.relationfield.interfaces import IRelationList
|
|
||||||
from z3c.relationfield.schema import RelationChoice, RelationList
|
|
||||||
|
|
||||||
from plone.formwidget.contenttree.widget import MultiContentTreeWidget
|
|
||||||
from plone.formwidget.contenttree.utils import closest_content
|
|
||||||
|
|
||||||
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
|
||||||
|
|
||||||
from .relatedkeywords import RelatedThesaurusKeywords
|
|
||||||
from .relatedkeywords import RelatedThesaurusKeywordsWidget
|
|
||||||
from .relatedkeywords import ThesaurusPathSourceBinder
|
|
||||||
|
|
||||||
class IBroaderThesaurusKeywords(IRelationList):
|
|
||||||
""""""
|
|
||||||
|
|
||||||
|
|
||||||
@adapter(IBroaderThesaurusKeywords, IFormLayer)
|
|
||||||
@implementer(IFieldWidget)
|
|
||||||
def BroaderThesaurusKeywordsFieldWidget(field, request):
|
|
||||||
return FieldWidget(field, RelatedThesaurusKeywordsWidget(
|
|
||||||
request, from_attribute='broader'))
|
|
||||||
|
|
||||||
class BroaderThesaurusKeywords(RelatedThesaurusKeywords):
|
|
||||||
implements(IBroaderThesaurusKeywords)
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
RelationList.__init__(self,
|
|
||||||
value_type=RelationChoice(
|
|
||||||
title=u'',
|
|
||||||
source=ThesaurusPathSourceBinder()),
|
|
||||||
**kwargs)
|
|
||||||
|
|
|
@ -20,8 +20,9 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<browser:page
|
<browser:page
|
||||||
for="collective.dms.thesaurus.dmskeyword.IDmsKeyword"
|
|
||||||
name="dmskeyword.view"
|
name="dmskeyword.view"
|
||||||
|
for="collective.dms.thesaurus.dmskeyword.IDmsKeyword"
|
||||||
|
layer="plone.app.z3cform.interfaces.IPloneFormLayer"
|
||||||
class="collective.dms.thesaurus.browser.view.DmsKeywordView"
|
class="collective.dms.thesaurus.browser.view.DmsKeywordView"
|
||||||
template="dmskeyword_view.pt"
|
template="dmskeyword_view.pt"
|
||||||
permission="zope2.View"
|
permission="zope2.View"
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
|
|
||||||
<metal:main fill-slot="main">
|
<metal:main fill-slot="main">
|
||||||
|
|
||||||
|
<h1 class="documentFirstHeading" tal:content="context/Title" />
|
||||||
|
<div tal:replace="structure provider:plone.belowcontenttitle" />
|
||||||
|
|
||||||
<div id="dmskeywords-navigation">
|
<div id="dmskeywords-navigation">
|
||||||
|
|
||||||
<tal:broader define="widget python:view.widgets.get('broader')">
|
<tal:broader define="widget python:view.widgets.get('broader')">
|
||||||
<div id="dmskeywords-navigation-broader"
|
<div id="dmskeywords-navigation-broader-field"
|
||||||
class="field"
|
class="field">
|
||||||
tal:condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',)">
|
|
||||||
<label tal:content="widget/label" />
|
<label tal:content="widget/label" />
|
||||||
<br />
|
<br />
|
||||||
<div tal:content="structure widget/render" />
|
<div tal:content="structure widget/render" />
|
||||||
|
@ -23,6 +25,18 @@
|
||||||
|
|
||||||
<div id="dmskeywords-navigation-middle">
|
<div id="dmskeywords-navigation-middle">
|
||||||
|
|
||||||
|
<h1 class="documentFirstHeading" tal:content="context/Title" />
|
||||||
|
<p class="documentDescription">
|
||||||
|
<tal:equivs define="widget python:view.widgets.get('equivs')"
|
||||||
|
condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',) and widget.terms()"
|
||||||
|
>[
|
||||||
|
<tal:equiv-terms repeat="value widget/terms"
|
||||||
|
><span tal:content="value"
|
||||||
|
/><span tal:condition="not:repeat/value/end"
|
||||||
|
tal:replace="python:', '"
|
||||||
|
/></tal:equiv-terms>
|
||||||
|
]</tal:equivs></p>
|
||||||
|
|
||||||
<dl class="portalMessage warning"
|
<dl class="portalMessage warning"
|
||||||
tal:define="widget python:view.widgets.get('scope_note')"
|
tal:define="widget python:view.widgets.get('scope_note')"
|
||||||
tal:condition="widget/value"
|
tal:condition="widget/value"
|
||||||
|
@ -37,32 +51,19 @@
|
||||||
<span tal:replace="structure widget/render" />
|
<span tal:replace="structure widget/render" />
|
||||||
</dd></dl>
|
</dd></dl>
|
||||||
|
|
||||||
<h1 class="documentFirstHeading" tal:content="context/Title" />
|
|
||||||
<p class="documentDescription">
|
|
||||||
<tal:equivs define="widget python:view.widgets.get('equivs')"
|
|
||||||
condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',) and widget.terms()"
|
|
||||||
>[
|
|
||||||
<tal:equiv-terms repeat="value widget/terms"
|
|
||||||
><span tal:content="value"
|
|
||||||
/><span tal:condition="not:repeat/value/end"
|
|
||||||
tal:replace="python:', '"
|
|
||||||
/></tal:equiv-terms>
|
|
||||||
]</tal:equivs></p>
|
|
||||||
<div tal:replace="structure provider:plone.belowcontenttitle" />
|
|
||||||
|
|
||||||
<tal:related define="widget python:view.widgets.get('related')">
|
<tal:related define="widget python:view.widgets.get('related')">
|
||||||
<div id="dmskeywords-navigation-related"
|
<div id="dmskeywords-navigation-related-field"
|
||||||
class="field"
|
class="field">
|
||||||
tal:condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',)">
|
<label tal:content="widget/label" />
|
||||||
<label tal:content="widget/label" />
|
<br />
|
||||||
<br />
|
<div tal:content="structure widget/render" />
|
||||||
<div tal:content="structure widget/render" />
|
</div>
|
||||||
</div>
|
|
||||||
</tal:related>
|
</tal:related>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field" id="dmskeywords-navigation-narrower">
|
<div class="field" id="dmskeywords-navigation-narrower-field">
|
||||||
<label tal:content="string:NT (Narrower Terms)" />
|
<label tal:content="string:NT (Narrower Terms)" />
|
||||||
<br />
|
<br />
|
||||||
<tal:list condition="view/children">
|
<tal:list condition="view/children">
|
||||||
|
|
|
@ -16,6 +16,8 @@ class DmsKeywordView(DefaultView):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def children(self):
|
def children(self):
|
||||||
|
return []
|
||||||
|
"""
|
||||||
intids = getUtility(IIntIds)
|
intids = getUtility(IIntIds)
|
||||||
catalog = getUtility(ICatalog)
|
catalog = getUtility(ICatalog)
|
||||||
value = []
|
value = []
|
||||||
|
@ -36,3 +38,4 @@ class DmsKeywordView(DefaultView):
|
||||||
value.append(tp)
|
value.append(tp)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
|
@ -19,12 +19,9 @@
|
||||||
<include package="." />
|
<include package="." />
|
||||||
<include package=".browser" />
|
<include package=".browser" />
|
||||||
|
|
||||||
<include file="widgets.zcml" />
|
<interface interface=".vocabulary.IMainThesaurus" />
|
||||||
|
|
||||||
<adapter factory=".relatedkeywords.RelatedThesaurusKeywordsFieldWidget" />
|
<include file="widgets.zcml" />
|
||||||
<adapter factory=".broaderkeywords.BroaderThesaurusKeywordsFieldWidget" />
|
|
||||||
<adapter factory=".equivalences.ThesaurusKeywordEquivalencesFieldWidget" />
|
|
||||||
<adapter factory=".field.ThesaurusKeywordsFieldWidget" />
|
|
||||||
|
|
||||||
<adapter
|
<adapter
|
||||||
name="SearchableText"
|
name="SearchableText"
|
||||||
|
|
|
@ -9,30 +9,31 @@ from plone.dexterity.content import Item
|
||||||
from plone.supermodel import model
|
from plone.supermodel import model
|
||||||
|
|
||||||
from . import _
|
from . import _
|
||||||
from .relatedkeywords import RelatedThesaurusKeywords
|
from .keywordsfield import ThesaurusKeywords
|
||||||
from .broaderkeywords import BroaderThesaurusKeywords
|
from .equivalencesfield import ThesaurusKeywordEquivalences
|
||||||
from .equivalences import ThesaurusKeywordEquivalences
|
|
||||||
|
|
||||||
class IDmsKeyword(model.Schema):
|
class IDmsKeyword(model.Schema):
|
||||||
""" """
|
""" """
|
||||||
|
|
||||||
# EQ: equivalences
|
# EQ: equivalences
|
||||||
equivs = ThesaurusKeywordEquivalences(
|
equivs = ThesaurusKeywordEquivalences(
|
||||||
title=u'EQ (Equivalences)',
|
title=_(u'EQ (Equivalences)'),
|
||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# BT: broader term
|
# BT: broader term
|
||||||
broader = BroaderThesaurusKeywords(
|
broader = ThesaurusKeywords(
|
||||||
title=_(u"BT (Broader Terms)"),
|
title=_(u"BT (Broader Terms)"),
|
||||||
required=False,
|
required=False,
|
||||||
|
vocabulary=u'dms.thesaurus.samesource'
|
||||||
)
|
)
|
||||||
|
|
||||||
# RT: related term
|
# RT: related term
|
||||||
related = RelatedThesaurusKeywords(
|
related = ThesaurusKeywords(
|
||||||
title=_(u"RT (Related Terms)"),
|
title=_(u"RT (Related Terms)"),
|
||||||
required=False,
|
required=False,
|
||||||
display_backrefs=True
|
display_backrefs=True,
|
||||||
|
vocabulary=u'dms.thesaurus.samesource'
|
||||||
)
|
)
|
||||||
|
|
||||||
# HN: historical note
|
# HN: historical note
|
||||||
|
|
|
@ -1,24 +1,35 @@
|
||||||
from zope.interface import implements, implementer
|
from zope.interface import implements, implementer
|
||||||
from zope.component import adapter, getUtility
|
from zope.component import adapter
|
||||||
|
#, getUtility
|
||||||
|
|
||||||
from zope import schema
|
from zope import schema
|
||||||
from zope.schema.interfaces import IList
|
from zope.schema.interfaces import IList
|
||||||
from zope.app.intid.interfaces import IIntIds
|
#from zope.app.intid.interfaces import IIntIds
|
||||||
|
|
||||||
from zc.relation.interfaces import ICatalog
|
#from zc.relation.interfaces import ICatalog
|
||||||
|
|
||||||
from z3c.form.interfaces import IFormLayer, IFieldWidget
|
from z3c.form.interfaces import IFormLayer, IFieldWidget
|
||||||
from z3c.form.widget import FieldWidget
|
from z3c.form.widget import FieldWidget
|
||||||
from z3c.form.browser.multi import MultiWidget
|
from z3c.form.browser.multi import MultiWidget
|
||||||
|
|
||||||
# #from z3c.relationfield.interfaces import IRelationList
|
#from z3c.relationfield.interfaces import IRelationList
|
||||||
#from z3c.relationfield.schema import RelationChoice, RelationList
|
#from z3c.relationfield.schema import RelationChoice, RelationList
|
||||||
|
|
||||||
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
#from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
||||||
|
|
||||||
class IThesaurusKeywordEquivalences(IList):
|
class IThesaurusKeywordEquivalences(IList):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
|
class ThesaurusKeywordEquivalences(schema.List):
|
||||||
|
implements(IThesaurusKeywordEquivalences)
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super(ThesaurusKeywordEquivalences, self).__init__(
|
||||||
|
value_type=schema.TextLine(
|
||||||
|
title=u'', required=False),
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ThesaurusKeywordEquivalencesWidget(MultiWidget):
|
class ThesaurusKeywordEquivalencesWidget(MultiWidget):
|
||||||
|
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
|
@ -33,12 +44,3 @@ class ThesaurusKeywordEquivalencesWidget(MultiWidget):
|
||||||
def ThesaurusKeywordEquivalencesFieldWidget(field, request):
|
def ThesaurusKeywordEquivalencesFieldWidget(field, request):
|
||||||
return FieldWidget(field, ThesaurusKeywordEquivalencesWidget(request))
|
return FieldWidget(field, ThesaurusKeywordEquivalencesWidget(request))
|
||||||
|
|
||||||
class ThesaurusKeywordEquivalences(schema.List):
|
|
||||||
implements(IThesaurusKeywordEquivalences)
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(ThesaurusKeywordEquivalences, self).__init__(
|
|
||||||
value_type=schema.TextLine(
|
|
||||||
title=u'', required=False),
|
|
||||||
**kwargs)
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
from zope.interface import implements, implementer
|
|
||||||
from zope.component import adapter
|
|
||||||
|
|
||||||
from z3c.form.interfaces import IFormLayer, IFieldWidget
|
|
||||||
from z3c.form.widget import FieldWidget
|
|
||||||
from z3c.relationfield.interfaces import IRelationList
|
|
||||||
from z3c.relationfield.schema import RelationChoice, RelationList
|
|
||||||
|
|
||||||
from plone.formwidget.contenttree.widget import MultiContentTreeWidget
|
|
||||||
from plone.formwidget.contenttree.utils import closest_content
|
|
||||||
from plone.formwidget.contenttree import ObjPathSourceBinder
|
|
||||||
|
|
||||||
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
|
||||||
|
|
||||||
class IThesaurusKeywords(IRelationList):
|
|
||||||
""""""
|
|
||||||
|
|
||||||
class ThesaurusKeywordsWidget(MultiContentTreeWidget):
|
|
||||||
display_template = ViewPageTemplateFile('thesaurus-keywords-display.pt')
|
|
||||||
|
|
||||||
def __init__(self, request):
|
|
||||||
super(ThesaurusKeywordsWidget, self).__init__(request)
|
|
||||||
|
|
||||||
def terms(self):
|
|
||||||
return [ x for x in self.value ]
|
|
||||||
|
|
||||||
|
|
||||||
@adapter(IThesaurusKeywords, IFormLayer)
|
|
||||||
@implementer(IFieldWidget)
|
|
||||||
def ThesaurusKeywordsFieldWidget(field, request):
|
|
||||||
return FieldWidget(field, ThesaurusKeywordsWidget(request))
|
|
||||||
|
|
||||||
class ThesaurusPathSourceBinder(ObjPathSourceBinder):
|
|
||||||
|
|
||||||
def __call__(self, context):
|
|
||||||
selectable_filter = self.selectable_filter
|
|
||||||
selectable_filter.criteria['portal_type'] = ('dmskeyword',)
|
|
||||||
#thesaurus_path = {'query': '/'.join(context.getPhysicalPath()[:-1])}
|
|
||||||
#selectable_filter.criteria['path'] = thesaurus_path
|
|
||||||
return self.path_source(
|
|
||||||
closest_content(context),
|
|
||||||
selectable_filter=selectable_filter,
|
|
||||||
navigation_tree_query=self.navigation_tree_query)
|
|
||||||
|
|
||||||
|
|
||||||
class ThesaurusKeywords(RelationList):
|
|
||||||
implements(IThesaurusKeywords)
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
RelationList.__init__(self,
|
|
||||||
value_type=RelationChoice(
|
|
||||||
title=u'',
|
|
||||||
source=ThesaurusPathSourceBinder()),
|
|
||||||
**kwargs)
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
from Acquisition import aq_parent
|
||||||
|
|
||||||
|
from zope import schema
|
||||||
|
from zope.interface import implements, implementer
|
||||||
|
from zope.component import adapter
|
||||||
|
|
||||||
|
#from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
||||||
|
from zope.schema.interfaces import ISet
|
||||||
|
from zope.schema.interfaces import IFromUnicode
|
||||||
|
from z3c.form.interfaces import IFormLayer, IFieldWidget, ISequenceWidget
|
||||||
|
#from z3c.form.interfaces import IWidget
|
||||||
|
from z3c.form.widget import FieldWidget, SequenceWidget
|
||||||
|
#from z3c.form.widget import Widget
|
||||||
|
#from z3c.form.browser.select import SelectWidget
|
||||||
|
|
||||||
|
|
||||||
|
from . import _
|
||||||
|
|
||||||
|
|
||||||
|
class IThesaurusKeywords(ISet):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ThesaurusKeywords(schema.Set):
|
||||||
|
implements(IThesaurusKeywords, IFromUnicode)
|
||||||
|
|
||||||
|
def __init__(self, display_backrefs=False, **kw):
|
||||||
|
self.display_backrefs = display_backrefs
|
||||||
|
vocabulary = kw.pop('vocabulary', u'dms.thesaurus.global')
|
||||||
|
super(ThesaurusKeywords, self).__init__(
|
||||||
|
value_type=schema.Choice(vocabulary=vocabulary),
|
||||||
|
**kw)
|
||||||
|
|
||||||
|
|
||||||
|
class IThesaurusKeywordsWidget(ISequenceWidget):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NoThesaurusFound(Exception):
|
||||||
|
"""No thesaurus found"""
|
||||||
|
|
||||||
|
|
||||||
|
class ThesaurusKeywordsWidget(SequenceWidget):
|
||||||
|
implements(IThesaurusKeywordsWidget)
|
||||||
|
|
||||||
|
def __init__(self, request, display_backrefs=False):
|
||||||
|
self.display_backrefs = display_backrefs
|
||||||
|
super(ThesaurusKeywordsWidget, self).__init__(request)
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
value = []
|
||||||
|
for token in self.value:
|
||||||
|
# Ignore no value entries. They are in the request only.
|
||||||
|
if token == self.noValueToken:
|
||||||
|
continue
|
||||||
|
term = self.terms.getTermByToken(token)
|
||||||
|
value.append({'id': token, 'value': term.value,
|
||||||
|
'content': term.title, 'selected': True
|
||||||
|
})
|
||||||
|
return value
|
||||||
|
|
||||||
|
def displayItems(self):
|
||||||
|
thesaurus = self.context
|
||||||
|
|
||||||
|
# XXX attention on remonte a partir d'un document ou d'un kw
|
||||||
|
|
||||||
|
value = []
|
||||||
|
for token in self.value:
|
||||||
|
# Ignore no value entries. They are in the request only.
|
||||||
|
if token == self.noValueToken:
|
||||||
|
continue
|
||||||
|
|
||||||
|
term = self.terms.getTermByToken(token)
|
||||||
|
|
||||||
|
value.append(
|
||||||
|
{'title': term.title,
|
||||||
|
'href': '#dummy',
|
||||||
|
})
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@adapter(IThesaurusKeywords, IFormLayer)
|
||||||
|
@implementer(IFieldWidget)
|
||||||
|
def ThesaurusKeywordsFieldWidget(field, request):
|
||||||
|
return FieldWidget(field, ThesaurusKeywordsWidget(
|
||||||
|
request, display_backrefs=field.display_backrefs))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<metadata>
|
<metadata>
|
||||||
<version>0001</version>
|
<version>0001</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>profile-plone.app.z3cform:default</dependency>
|
||||||
<dependency>profile-plone.app.dexterity:default</dependency>
|
<dependency>profile-plone.app.dexterity:default</dependency>
|
||||||
<dependency>profile-plone.app.intid:default</dependency>
|
<dependency>profile-plone.app.intid:default</dependency>
|
||||||
<dependency>profile-collective.dms.thesaurus:default</dependency>
|
<dependency>profile-collective.dms.thesaurus:default</dependency>
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
<ul id="" class=""
|
|
||||||
tal:condition="view/dictvalues"
|
|
||||||
tal:attributes="id view/id;
|
|
||||||
class view/klass;
|
|
||||||
style view/style;
|
|
||||||
title view/title;
|
|
||||||
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
|
|
||||||
"><li tal:repeat="value view/dictvalues"
|
|
||||||
><a class="selected-option"
|
|
||||||
href="#"
|
|
||||||
tal:content="value/label"
|
|
||||||
tal:attributes="href value/url"
|
|
||||||
/></li
|
|
||||||
></ul>
|
|
||||||
<em tal:condition="not:view/dictvalues">(nothing)</em>
|
|
|
@ -1,102 +0,0 @@
|
||||||
from zope.interface import implements, implementer
|
|
||||||
from zope.component import adapter, getUtility
|
|
||||||
from zope.app.intid.interfaces import IIntIds
|
|
||||||
|
|
||||||
from zc.relation.interfaces import ICatalog
|
|
||||||
|
|
||||||
from z3c.form.interfaces import IFormLayer, IFieldWidget
|
|
||||||
from z3c.form.widget import FieldWidget
|
|
||||||
from z3c.relationfield.interfaces import IRelationList
|
|
||||||
from z3c.relationfield.schema import RelationChoice, RelationList
|
|
||||||
|
|
||||||
from plone.formwidget.contenttree.widget import MultiContentTreeWidget
|
|
||||||
from plone.formwidget.contenttree.utils import closest_content
|
|
||||||
from plone.formwidget.contenttree import ObjPathSourceBinder
|
|
||||||
|
|
||||||
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
|
||||||
|
|
||||||
class IRelatedThesaurusKeywords(IRelationList):
|
|
||||||
""""""
|
|
||||||
|
|
||||||
class RelatedThesaurusKeywordsWidget(MultiContentTreeWidget):
|
|
||||||
display_template = ViewPageTemplateFile('related-thesaurus-keywords-display.pt')
|
|
||||||
|
|
||||||
def __init__(self, request, from_attribute='related', display_backrefs=False):
|
|
||||||
self.from_attribute = from_attribute
|
|
||||||
self.display_backrefs = display_backrefs
|
|
||||||
super(RelatedThesaurusKeywordsWidget, self).__init__(request)
|
|
||||||
|
|
||||||
def get_url(self, v):
|
|
||||||
return v
|
|
||||||
|
|
||||||
def get_term(self, v):
|
|
||||||
return self.terms.getTermByToken(v)
|
|
||||||
|
|
||||||
def get_label(self, v):
|
|
||||||
return self.get_term(v).title
|
|
||||||
|
|
||||||
def get_hn(self, v):
|
|
||||||
return self.get_term(v).value.historical_note
|
|
||||||
|
|
||||||
def get_sn(self, v):
|
|
||||||
return self.get_term(v).value.scope_note
|
|
||||||
|
|
||||||
def dictvalues(self):
|
|
||||||
refs = [dict(
|
|
||||||
url=self.get_url(x),
|
|
||||||
label=self.get_label(x),
|
|
||||||
hn=self.get_hn(x),
|
|
||||||
sn=self.get_sn(x),
|
|
||||||
) for x in self.value]
|
|
||||||
if self.display_backrefs:
|
|
||||||
intids = getUtility(IIntIds)
|
|
||||||
catalog = getUtility(ICatalog)
|
|
||||||
try:
|
|
||||||
doc_intid = intids.getId(self.context)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
for ref in catalog.findRelations(
|
|
||||||
{'to_id': doc_intid,
|
|
||||||
'from_attribute': self.from_attribute}):
|
|
||||||
tp = dict(
|
|
||||||
url=ref.from_path,
|
|
||||||
label=ref.from_object.Title(),
|
|
||||||
hn=ref.from_object.historical_note,
|
|
||||||
sn=ref.from_object.scope_note
|
|
||||||
)
|
|
||||||
if tp not in refs:
|
|
||||||
refs.append(tp)
|
|
||||||
return refs
|
|
||||||
|
|
||||||
|
|
||||||
@adapter(IRelatedThesaurusKeywords, IFormLayer)
|
|
||||||
@implementer(IFieldWidget)
|
|
||||||
def RelatedThesaurusKeywordsFieldWidget(field, request):
|
|
||||||
return FieldWidget(field, RelatedThesaurusKeywordsWidget(
|
|
||||||
request, display_backrefs=field.display_backrefs))
|
|
||||||
|
|
||||||
class ThesaurusPathSourceBinder(ObjPathSourceBinder):
|
|
||||||
|
|
||||||
def __call__(self, context):
|
|
||||||
selectable_filter = self.selectable_filter
|
|
||||||
selectable_filter.criteria['portal_type'] = ('dmskeyword',)
|
|
||||||
thesaurus_path = {'query': '/'.join(context.getPhysicalPath()[:-1])}
|
|
||||||
selectable_filter.criteria['path'] = thesaurus_path
|
|
||||||
return self.path_source(
|
|
||||||
closest_content(context),
|
|
||||||
selectable_filter=selectable_filter,
|
|
||||||
navigation_tree_query=self.navigation_tree_query)
|
|
||||||
|
|
||||||
|
|
||||||
class RelatedThesaurusKeywords(RelationList):
|
|
||||||
implements(IRelatedThesaurusKeywords)
|
|
||||||
|
|
||||||
def __init__(self, display_backrefs=False, **kwargs):
|
|
||||||
self.display_backrefs = display_backrefs
|
|
||||||
RelationList.__init__(self,
|
|
||||||
value_type=RelationChoice(
|
|
||||||
title=u'',
|
|
||||||
source=ThesaurusPathSourceBinder()),
|
|
||||||
**kwargs)
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
<ul id="" class=""
|
|
||||||
tal:condition="view/terms"
|
|
||||||
tal:attributes="id view/id;
|
|
||||||
class view/klass;
|
|
||||||
style view/style;
|
|
||||||
title view/title;
|
|
||||||
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"><li
|
|
||||||
tal:repeat="item view/terms"
|
|
||||||
><span tal:replace="item/title" /></li></ul
|
|
||||||
><em tal:condition="not:view/value">(nothing)</em>
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<ul id="" class=""
|
||||||
|
tal:condition="view/displayItems"
|
||||||
|
tal:define="th_url python:'/'.join(view.context.absolute_url().split('/')[:-1]);"
|
||||||
|
tal:attributes="id view/id"
|
||||||
|
><li tal:repeat="value view/displayItems"><a href=""
|
||||||
|
tal:content="value/title"
|
||||||
|
tal:attributes="href value/href"
|
||||||
|
/></li
|
||||||
|
></ul>
|
||||||
|
<em tal:condition="not:view/displayItems"
|
||||||
|
i18n:translate="">none</em>
|
|
@ -0,0 +1,52 @@
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:tal="http://xml.zope.org/namespaces/tal"
|
||||||
|
tal:omit-tag="">
|
||||||
|
<select id="" name="" class="" tabindex="" disabled="" multiple="multiple" size="5"
|
||||||
|
style="display: none;"
|
||||||
|
tal:attributes="id view/id;
|
||||||
|
name string:${view/name}:list">
|
||||||
|
<tal:block repeat="item view/items"
|
||||||
|
><option id="" value="" selected="selected"
|
||||||
|
tal:condition="item/selected"
|
||||||
|
tal:attributes="id item/id;
|
||||||
|
value item/value"
|
||||||
|
tal:content="item/content">label</option
|
||||||
|
><option id="" value=""
|
||||||
|
tal:condition="not:item/selected"
|
||||||
|
tal:attributes="id item/id;
|
||||||
|
value item/value"
|
||||||
|
tal:content="item/content">label</option
|
||||||
|
></tal:block>
|
||||||
|
</select>
|
||||||
|
<input name="field-empty-marker" type="hidden" value="1"
|
||||||
|
tal:attributes="name string:${view/name}-empty-marker" />
|
||||||
|
|
||||||
|
<span id="" class=""><tal:block
|
||||||
|
tal:repeat="item view/items"
|
||||||
|
><span class="selected-option"
|
||||||
|
tal:attributes="data-term-id item/value">
|
||||||
|
<span tal:content="item/content"
|
||||||
|
/> <span class="remove">×</span></span><tal:block condition="not:repeat/item/end">, </tal:block
|
||||||
|
></tal:block
|
||||||
|
></span>
|
||||||
|
|
||||||
|
<!--script type="text/javascript" tal:content="structure view/js"></script-->
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
span.selected-option {
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #eef;
|
||||||
|
padding: 0.5ex 1ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.remove {
|
||||||
|
margin-left: 1ex;
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<button onclick="return false;">Add</button>
|
||||||
|
</div>
|
|
@ -5,20 +5,21 @@ from zope.app.intid.interfaces import IIntIds
|
||||||
from z3c.relationfield import RelationValue
|
from z3c.relationfield import RelationValue
|
||||||
from Products.Five.browser import BrowserView
|
from Products.Five.browser import BrowserView
|
||||||
|
|
||||||
|
from zope.component import getUtility
|
||||||
|
from zope.schema.interfaces import IVocabularyFactory
|
||||||
|
|
||||||
from zope.event import notify
|
from zope.event import notify
|
||||||
from zope.lifecycleevent import ObjectAddedEvent, ObjectModifiedEvent
|
from zope.lifecycleevent import ObjectAddedEvent, ObjectModifiedEvent
|
||||||
|
|
||||||
|
|
||||||
class ImportJson(BrowserView):
|
class ImportJson(BrowserView):
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
self.intids = component.getUtility(IIntIds)
|
|
||||||
|
|
||||||
path = '/tmp/thesaurus.json'
|
path = '/tmp/thesaurus.json'
|
||||||
# XXX: replace with a path given in the query string, or load json
|
# XXX: replace with a path given in the query string, or load json
|
||||||
# from POST data
|
# from POST data
|
||||||
|
|
||||||
terms = json.load(file(path))
|
terms = json.load(file(path))
|
||||||
term_intids = {}
|
|
||||||
|
|
||||||
# 1st step; create object for terms
|
# 1st step; create object for terms
|
||||||
for term_id, term in terms.items():
|
for term_id, term in terms.items():
|
||||||
|
@ -29,21 +30,20 @@ class ImportJson(BrowserView):
|
||||||
title=term.get('title'))
|
title=term.get('title'))
|
||||||
object = getattr(self.context, term_id)
|
object = getattr(self.context, term_id)
|
||||||
notify(ObjectAddedEvent(object))
|
notify(ObjectAddedEvent(object))
|
||||||
try:
|
#try:
|
||||||
term_intids[term_id] = self.intids.getId(object)
|
# term_intids[term_id] = self.intids.getId(object)
|
||||||
except KeyError:
|
#except KeyError:
|
||||||
self.intids.register(object)
|
# self.intids.register(object)
|
||||||
object.title = term.get('title')
|
object.title = term.get('title')
|
||||||
object.historical_note = term.get('historical_note')
|
object.historical_note = term.get('historical_note')
|
||||||
object.scope_note = term.get('scope_note')
|
object.scope_note = term.get('scope_note')
|
||||||
object.equivs = term.get('equivalents')
|
object.equivs = term.get('equivalents')
|
||||||
term_intids[term_id] = self.intids.getId(object)
|
|
||||||
|
|
||||||
# 2nd step; add relations
|
# 2nd step; add relations
|
||||||
for term_id, term in terms.items():
|
for term_id, term in terms.items():
|
||||||
object = getattr(self.context, term_id)
|
object = getattr(self.context, term_id)
|
||||||
object.related = [RelationValue(term_intids[x]) for x in term.get('related', [])]
|
object.related = [x for x in term.get('related', [])]
|
||||||
object.broader = [RelationValue(term_intids[x]) for x in term.get('parents', [])]
|
object.broader = [x for x in term.get('parents', [])]
|
||||||
notify(ObjectModifiedEvent(object))
|
notify(ObjectModifiedEvent(object))
|
||||||
|
|
||||||
return 'OK'
|
return 'OK'
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
from zope.interface import Interface
|
||||||
|
#from zope.interface import implements
|
||||||
|
from five import grok
|
||||||
|
|
||||||
|
#from zope.component import queryUtility
|
||||||
|
from zope.schema.interfaces import IVocabularyFactory
|
||||||
|
#from zope.schema.interfaces import ISource, IContextSourceBinder
|
||||||
|
from zope.schema.vocabulary import SimpleVocabulary
|
||||||
|
#from zope.schema.vocabulary import SimpleTerm
|
||||||
|
|
||||||
|
from Products.CMFCore.utils import getToolByName
|
||||||
|
|
||||||
|
|
||||||
|
class IMainThesaurus(Interface):
|
||||||
|
""" Marker interface for main thesaurus container
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalThesaurusSource(object):
|
||||||
|
grok.implements(IVocabularyFactory)
|
||||||
|
|
||||||
|
def __call__(self, context):
|
||||||
|
catalog = getToolByName(context, 'portal_catalog')
|
||||||
|
results = catalog(portal_type='dmskeyword')
|
||||||
|
keywords = [x.getObject() for x in results]
|
||||||
|
def cmp_keyword(x, y):
|
||||||
|
return cmp(x.title, y.title)
|
||||||
|
keywords.sort(cmp_keyword)
|
||||||
|
keyword_ids = [x.id for x in keywords]
|
||||||
|
keyword_terms = [SimpleVocabulary.createTerm(
|
||||||
|
x.id, x.id, x.title) for x in keywords]
|
||||||
|
return SimpleVocabulary(keyword_terms)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
# hack to let schema editor handle the field
|
||||||
|
yield u'DO NOT TOUCH'
|
||||||
|
|
||||||
|
|
||||||
|
grok.global_utility(GlobalThesaurusSource,
|
||||||
|
name=u'dms.thesaurus.global')
|
||||||
|
|
||||||
|
class KeywordFromSameThesaurusSource(object):
|
||||||
|
grok.implements(IVocabularyFactory)
|
||||||
|
|
||||||
|
def __call__(self, context):
|
||||||
|
#XXX: need to add url filter
|
||||||
|
catalog = getToolByName(context, 'portal_catalog')
|
||||||
|
results = catalog(portal_type='dmskeyword')
|
||||||
|
keywords = [x.getObject() for x in results]
|
||||||
|
def cmp_keyword(x, y):
|
||||||
|
return cmp(x.title, y.title)
|
||||||
|
keywords.sort(cmp_keyword)
|
||||||
|
keyword_ids = [x.id for x in keywords]
|
||||||
|
keyword_terms = [SimpleVocabulary.createTerm(
|
||||||
|
x.id, x.id, x.title) for x in keywords]
|
||||||
|
return SimpleVocabulary(keyword_terms)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
# hack to let schema editor handle the field
|
||||||
|
yield u'DO NOT TOUCH'
|
||||||
|
|
||||||
|
|
||||||
|
grok.global_utility(KeywordFromSameThesaurusSource,
|
||||||
|
name=u'dms.thesaurus.samesource')
|
|
@ -3,11 +3,30 @@
|
||||||
xmlns:browser="http://namespaces.zope.org/browser"
|
xmlns:browser="http://namespaces.zope.org/browser"
|
||||||
xmlns:z3c="http://namespaces.zope.org/z3c">
|
xmlns:z3c="http://namespaces.zope.org/z3c">
|
||||||
|
|
||||||
<z3c:widgetTemplate
|
<!-- thesaurus keywords widget, used in other types schema -->
|
||||||
mode="display"
|
<adapter factory=".keywordsfield.ThesaurusKeywordsFieldWidget"/>
|
||||||
widget=".equivalences.ThesaurusKeywordEquivalencesWidget"
|
|
||||||
layer="z3c.form.interfaces.IFormLayer"
|
<z3c:widgetTemplate
|
||||||
template="thesaurus-keyword-equivs-display.pt"
|
mode="display"
|
||||||
/>
|
widget=".keywordsfield.IThesaurusKeywordsWidget"
|
||||||
|
layer="z3c.form.interfaces.IFormLayer"
|
||||||
|
template="thesauruskeywords_display.pt"/>
|
||||||
|
|
||||||
|
<z3c:widgetTemplate
|
||||||
|
mode="input"
|
||||||
|
widget=".keywordsfield.IThesaurusKeywordsWidget"
|
||||||
|
layer="z3c.form.interfaces.IFormLayer"
|
||||||
|
template="thesauruskeywords_input.pt"/>
|
||||||
|
|
||||||
|
<!-- keyword equivalences widget, used in keyword schema -->
|
||||||
|
<adapter factory=".equivalencesfield.ThesaurusKeywordEquivalencesFieldWidget" />
|
||||||
|
|
||||||
|
<z3c:widgetTemplate
|
||||||
|
mode="display"
|
||||||
|
widget=".equivalencesfield.ThesaurusKeywordEquivalencesWidget"
|
||||||
|
layer="z3c.form.interfaces.IFormLayer"
|
||||||
|
template="thesaurus-keyword-equivs-display.pt"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
</configure>
|
</configure>
|
||||||
|
|
Reference in New Issue