如何将文件夹类型中特殊 content_type 对象的数量限制为仅一个对象?

发布于 2024-11-19 16:55:22 字数 53 浏览 0 评论 0原文

我正在创建一个文件夹类型(原型 1),并且我希望能够仅将单个对象(原型 2)添加到此文件夹。

I am creating a folderish type (archetype 1) and I want to have possibility to add only a single object of (archetype 2) to this folder.

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

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

发布评论

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

评论(4

吲‖鸣 2024-11-26 16:55:23

您可以通过修改“archetypes 1”类型定义(profiles/default/archetype1.xml)将文件夹类型(“archetype 1”)内的可添加类型限制为“archetype 2”:

<?xml version="1.0"?>
<object name="archetype1">
   ...
  <property name="filter_content_types">True</property>  
  <property name="allowed_content_types">
    <element value="archetype2" />
  </property>
  ...
</object>

You can restrict the addable types inside your folderish type ("archetype 1") to "archetype 2" by amending the "archetypes 1" types definition (profiles/default/archetype1.xml):

<?xml version="1.0"?>
<object name="archetype1">
   ...
  <property name="filter_content_types">True</property>  
  <property name="allowed_content_types">
    <element value="archetype2" />
  </property>
  ...
</object>
魂归处 2024-11-26 16:55:23

好的,那么您希望第二种类型 archetype 2 只能在 archetype 1 中添加一次?

我会这样做,绿色编辑栏上的添加新下拉列表仅显示原型2(如果可以添加的话)(这里的其他解决方案要求用户首先呈现添加表单,然后被告知这是不允许的)。

您需要确保您的文件夹archetype 1子类ConstrainTypesMixin

我认为如果您在 Products.ATContentTypes 中使用文件夹式内容类型,您将自动对这个 mixin 类进行子类化,但这有助于确保。

然后,在原型 1 中添加方法:getLocallyAllowedTypes。此方法在 Products/ATContentTypes/lib/constraintypes.pyConstrainTypesMixin 类中声明。

在此方法中,您现在可以添加逻辑来检查 的实例是否存在原型 2 已添加。如果有,请勿将其作为本地允许的类型之一返回。如果没有,则返回它(如果存在其他类型)。

确保首先在此方法中调用 super() 以从超类的方法中获取本地添加的类型。

要了解其工作原理,您可以查看 plone/app/contentmenu/menu.pyFactoriesSubMenuItem 类中的 *_addableTypesInContext* 方法,了解何时以及如何< em>getLocallyAllowedTypes 方法被调用。

Ok, so you want your second type archetype 2 to be addable only once inside archetype 1?

I would do it in such a way that the Add New dropdown on the green edit bar only shows archetype 2 if it can be added (the other solutions here require the user to first render the add form and then be told that this is not allowed).

You need to make sure that your folderish archetype 1 subclasses ConstrainTypesMixin.

I think if you use the folderish content types in Products.ATContentTypes you will automatically subclass this mixin class, but it helps to make sure.

Then, inside archetype 1, add the method: getLocallyAllowedTypes. This method is declared in the ConstrainTypesMixin class in Products/ATContentTypes/lib/constraintypes.py

In this method you can now add the logic to check if an instance of archetype 2 has already been added. If it has, don't return it as one of the locally allowed types. If it hasn't, then return it (with the other types if they exist).

Make sure to first call super() in this method to get the locally added types from the superclass's method.

To understand how this works, you can look at the *_addableTypesInContext* method in the FactoriesSubMenuItem class in plone/app/contentmenu/menu.py to see when and how this getLocallyAllowedTypes method is called.

街角迷惘 2024-11-26 16:55:23

您可能最好创建一个自定义添加表单(可能使用 z3c.form)并在那里放置限制。

You are probably best off creating a custom add form (perhaps using z3c.form) and making the placing the restriction there.

可爱暴击 2024-11-26 16:55:23

您可以覆盖 createObject.cpy 脚本并在其中添加检查:

this_type = REQUEST.form.get('type_name') 
if this_type == 'MyATContentType':
    # MyATContentType needs a special check
    ctool = getToolByName(context, 'portal_catalog')
    this_path = '/'.join(context.getPhysicalPath())

    # Query the Catalog to see we already have an instance of this object here
    results = ctool.searchResults({'portal_type': this_type, 'path': this_path})

    if results:
        context.plone_utils.addPortalMessage(_(
            u'Sorry, but there already is an object of type %s here.' % this_type
        ))

        # Redirect to the edit form of the first found object.
        cv = results[0]
        cv_path = cv.getPath()
        return context.REQUEST.RESPONSE.redirect(cv_path + "/edit")

在产品的外观/模板文件夹中提供自定义脚本以及关联的 .metadata 文件。

额外提示:在 Dexterity 中,您可以在 dexterity.AddForm.update() 中添加此检查

You can override the createObject.cpy script and add a check there:

this_type = REQUEST.form.get('type_name') 
if this_type == 'MyATContentType':
    # MyATContentType needs a special check
    ctool = getToolByName(context, 'portal_catalog')
    this_path = '/'.join(context.getPhysicalPath())

    # Query the Catalog to see we already have an instance of this object here
    results = ctool.searchResults({'portal_type': this_type, 'path': this_path})

    if results:
        context.plone_utils.addPortalMessage(_(
            u'Sorry, but there already is an object of type %s here.' % this_type
        ))

        # Redirect to the edit form of the first found object.
        cv = results[0]
        cv_path = cv.getPath()
        return context.REQUEST.RESPONSE.redirect(cv_path + "/edit")

Provide the customized script, together with the associated .metadata file, in the skins/templates folder of your product.

Bonus tip: In Dexterity, you would add this check in dexterity.AddForm.update()

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