是否可以根据注释中保存的术语定义词汇表?

问题描述 投票:0回答:1

上下文:我有一种简单的方法可以在注释中保存一些 json 数据(在门户对象上)。这个定义有时会改变,所以我只上传新的 json。

我正在尝试为我的内容类型创建一种行为:一个新字段,用于保存您从当前定义中选择的术语。

问题是我无法从用于填充词汇表的函数中访问注释。我得到:

(Pdb) from plone import api
(Pdb) api.portal.get()
*** plone.api.exc.CannotGetPortalError: Unable to get the portal object. More info on https://docs.plone.org/develop/plone.api/docs/api/exceptions.html#plone.api.exc.CannotGetPortalError

这就是我现在拥有的:

vocabulary.py

def generic_vocabulary(_terms, sort=True):
    """Returns a zope vocabulary from a dict or a list"""

    if _terms and isinstance(_terms, dict):
        _terms = _terms.items()
    elif _terms and isinstance(_terms[0], str):
        _terms = [(x, x) for x in _terms]

    if sort:
        _terms = sorted(_terms, key=lambda x: x[0])

    def factory(context):
        """Simple Vocabulary factory"""
        return SimpleVocabulary(
            [SimpleTerm(n, n.encode("utf-8"), term) for n, term in _terms]
        )

    return factory


_terms_list = (
    ("key1", "Value 1"),
    ("key2", "Value 2"),    
)


def generate_terms_list():
    import pdb

    pdb.set_trace()

    # TODO Get the list of terms from annotations
    # from plone import api
    # api.portal.get() ERROR HERE
    return _terms_list


terms_list = generic_vocabulary(generate_terms_list())
alsoProvides(terms_list, IVocabularyFactory)

configure.zcml

  <utility
    name="my.add.on.terms"
    component=".vocabulary.terms_list"
    />

behavior.py

from plone.autoform import directives
from plone.autoform.interfaces import IFormFieldProvider
from plone.supermodel import model
from zope import schema
from zope.interface import provider


@provider(IFormFieldProvider)
class ICustomTermsListBehavior(model.Schema):
    
    terms_list = schema.List(
        title="Terms List",
        description="Select Terms",
        required=False,
        value_type=schema.Choice(vocabulary="my.add.on.terms"),
    )
    directives.write_permission(terms_list="cmf.ManagePortal")

如果我使用

_terms_list
,代码将按预期工作。现在我只想用注释中的真实内容替换这些演示术语:

def get_annot():
    annot_key = 'TEST_KEY'
    container = api.portal.get()
    annotations = IAnnotations(container)
    return annotations[annot_key]

如何修复

plone.api.exc.CannotGetPortalError: Unable to get the portal object
错误,并从注释中获取数据?

更新:

也已经尝试过:

(Pdb) from zope.component import getUtility
(Pdb) from Products.CMFCore.interfaces import ISiteRoot
(Pdb) portal = getUtility(ISiteRoot)
*** zope.interface.interfaces.ComponentLookupError: (<InterfaceClass Products.CMFCore.interfaces.ISiteRoot>, '')

同样适用于:

(Pdb) site = api.portal.getSite()
(Pdb) site is None
True

不工作:

(Pdb) from zope.component.hooks import getSite
(Pdb) getSite() is None
True
plone plone-6
1个回答
0
投票

答案是:是的。

我在这里找到它:https://5.docs.plone.org/external/plone.app.dexterity/docs/advanced/vocabularies.html#dynamic-sources

解决方法:

def generate_terms_list(context):
    terms = [(str(x["id"]), str(x["value"])) for x in get_annot()]
    return terms

@provider(IContextSourceBinder)
def get_terms(context):
    return generic_vocabulary(generate_terms_list(context))(context)

...

@provider(IFormFieldProvider)
class ICustomTermsListBehavior(model.Schema):
    
    terms_list = schema.List(
        title="Terms List",
        description="Select Terms",
        required=False,
        value_type=schema.Choice(source=get_terms),
    )
    directives.write_permission(terms_list="cmf.ManagePortal")

注意来源而不是词汇

@provider(IContextSourceBinder)
+ 上下文

© www.soinside.com 2019 - 2024. All rights reserved.