如何以编程方式控制对象的允许内容类型的添加菜单列表?

发布于 2024-10-20 04:45:37 字数 1126 浏览 1 评论 0原文

我想实用地控制单个对象的允许内容类型的添加菜单列表。

我正在使用 archgenxml 构建内容类型的集合。在一种情况下,我有一个由 RangeBase 类组成的模拟类,该类具有三个实现:valueRange、vectorRange 和uniformRange。模拟可以恰好包含一个范围,即 RangeBase 的重数为一,因此模拟的添加菜单应该提供所有三种范围类型,或者根本不提供。

为了实现这一点,我想订阅 IObjectInitializedEvent 和 IObjectRemovedEvent 事件;将它们各自的处理程序initializedHook 和removedHook 放置在RangeBase 类中。处理程序将请求对象的本地允许类型列表,并相应地删除或添加三个范围。在仔细阅读了 Plone 的“社区开发人员文档”后,我认为初始化Hook 代码可能如下所示:

  # Set allowed content types
  from Products.ATContentTypes.lib import constraintypes

  def initializedHook(obj, event):

    # Get this range's parent simulation
    parent = obj.aq_parent

    # Enable constraining
    parent.setConstrainTypesMode(constraintypes.ENABLED)

    # Remove the three ranges 
    allowedTypes = parent.getLocallyAllowedTypes()
    ranges = ('valueRange','vectorRange','uniformRange')
    for range in ranges:
      allowedTypes.remove(range)

    # Tweak the menu
    parent.setLocallyAllowedTypes(allowedTypes)
    parent.setImmediatelyAddableTypes(allowedTypes)

不幸的是,我的模拟类没有这些功能。

是否有一个适配器可以为我的模拟类提供此功能,或者是否有其他完全不同的方法来实现所需的菜单行为?任何建议将不胜感激。

I would like pragmatically to control individual objects' add-menu list of allowed content types.

I am building a collection of content types with archgenxml. In one case, I have a simulation class composed of a RangeBase class which has three realizations, valueRange, vectorRange and uniformRange. A simulation can contain exactly one range, i.e., RangeBase's multiplicity is one, so a simulation's add-menu should offer either all three range types or none at all.

To achieve this, I thought to subscribed to the IObjectInitializedEvent and IObjectRemovedEvent events; placing their respective handlers, initializedHook and removedHook, in the RangeBase class. The handlers would solicit an object's list of locally allowed types and remove or add the three ranges accordingly. After perusing the Plone's 'Community Developer Documentation', I thought the initializedHook code might look something like this:

  # Set allowed content types
  from Products.ATContentTypes.lib import constraintypes

  def initializedHook(obj, event):

    # Get this range's parent simulation
    parent = obj.aq_parent

    # Enable constraining
    parent.setConstrainTypesMode(constraintypes.ENABLED)

    # Remove the three ranges 
    allowedTypes = parent.getLocallyAllowedTypes()
    ranges = ('valueRange','vectorRange','uniformRange')
    for range in ranges:
      allowedTypes.remove(range)

    # Tweak the menu
    parent.setLocallyAllowedTypes(allowedTypes)
    parent.setImmediatelyAddableTypes(allowedTypes)

Unfortunately, my simulation class has none of these functions.

Is there an adaptor that will provide my simulation class with this functionality, or are there other altogether different approaches to achieve the desired menu behaviour? Any suggestions would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只是一片海 2024-10-27 04:45:37

这是可能的。

我相信您需要重写 getLocallyAllowedType()

http://svn.plone.org/svn/collective/Products.ATContentTypes/trunk/Products/ATContentTypes/lib/constraintypes.py

AT 是在适配器之前编写的,因此 AT 没有使用它。

我建议您也可以更新有关此的文档...这是非常常见的用例。

http://web.archive .org/web/20101010142032/http://collective-docs.plone.org/content/creating.html

It is possible.

I believe you need to override getLocallyAllowedType()

http://svn.plone.org/svn/collective/Products.ATContentTypes/trunk/Products/ATContentTypes/lib/constraintypes.py

AT was written time before adapters, so AT is not using it.

I suggest you could also update the documentation regarding this... it is pretty common use case.

http://web.archive.org/web/20101010142032/http://collective-docs.plone.org/content/creating.html

逆光飞翔i 2024-10-27 04:45:37

在多次尝试调整 _allowedTypes() 失败后,我遵循了 http://plone 的最后建议.org/documentation/kb/restrict-addable-types 和自定义的 getNotAddableTypes.py。我的自定义仅列出了三个范围的文件夹内容过滤。如果生成的数组不为空,我会将三种范围类型添加到列表中:

 # customize this script to filter addable portal types based on
 # context, the current user or other criteria

 ranges = []
 ranges = context.listFolderContents(contentFilter={'portal_type':
                     ('VectorRange','ValueRange','UniformRange')})
 return {True:  ('Favorite', 'VectorRange', 'ValueRange', 'UniformRange'),
         False: ('Favorite')}[len(ranges)]

After several unsuccessful attempts at tweaking _allowedTypes(), I followed the last suggestion at http://plone.org/documentation/kb/restrict-addable-types and customized getNotAddableTypes.py. My customization merely lists a folder's contents filtering for the three ranges. If the resulting array is not empty, I add the three range types to the list:

 # customize this script to filter addable portal types based on
 # context, the current user or other criteria

 ranges = []
 ranges = context.listFolderContents(contentFilter={'portal_type':
                     ('VectorRange','ValueRange','UniformRange')})
 return {True:  ('Favorite', 'VectorRange', 'ValueRange', 'UniformRange'),
         False: ('Favorite')}[len(ranges)]
我是有多爱你 2024-10-27 04:45:37

该方法

foo.getLocallyAllowedTypes()

返回一个元组,您只需将其复制/过滤到另一个元组/列表中,因为它是不可变的。

allowed_types = parent.getLocallyAllowedTypes()
filtered_types = []
for v in allowed_types:
    if not v in ranges:
        filtered_types.append(v)

然后,您只需将该元组提供给 setter 方法即可

parent.setLocallyAllowedTypes(filtered_types)

。但是,如果您想在对象创建期间访问父级以限制您在其中创建对象的文件夹的内容类型,则可以从 BaseObject 连接 at_post_create_script() 和 manage_beforeDelete() 。这对我来说非常有用,可以限制文件夹中特定内容类型的数量,并且还可以在对象被删除时更正AllowedTypes。

The method

foo.getLocallyAllowedTypes()

gives back a tuple, that you just have to copy / filter into another tuple / list, because it's immutable.

allowed_types = parent.getLocallyAllowedTypes()
filtered_types = []
for v in allowed_types:
    if not v in ranges:
        filtered_types.append(v)

Then you can just give that tuple to the setter method

parent.setLocallyAllowedTypes(filtered_types)

and your're done. But if you want to access the parent during object creation to restrict content types of the folder, you creating the object in, you can hook up in at_post_create_script() and manage_beforeDelete() from BaseObject. This works great for me, restricting the number of specific content types to a folder and also corrects the AllowedTypes when the object gets deleted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文