Limiting one Content item per Member in a Folder on Plone 4
Asked Answered
D

3

7

I have created a custom Archetypes content type called "Résumé" and would like to enforce a limitation that lets a Member add only one item of this type inside a folder. Even better would be redirecting the member to the edit page of his or her item, if it already exists in that folder.

How can I enforce this limitation and provide this extra functionality?

Denudate answered 29/4, 2011 at 13:47 Comment(1)
I posted my solution here: pastie.org/1856465 based on the suggestions of zupo.Denudate
C
5

A solution to a similar usecase for Plone 3 can be found in the eestec.base. We did it by overriding the createObject.cpy and adding a special check for this.

Code is in the collective SVN, at http://dev.plone.org/collective/browser/eestec.base/trunk/eestec/base/skins/eestec_base_templates/createObject.cpy, lines 20-32.

Chemo answered 29/4, 2011 at 14:21 Comment(1)
Thanks. That's exactly what I was looking for, i.e. a hook that does a check before the content creation part, and redirects the user to the relative edit view if it already exists.Denudate
I
2

Well, it is a sort of validation constraint, so maybe add a validator to the title field that in reality does not bother about the title, but checks the user etc.? (I think a field validator is passed enough information to pull this off, if not, overriding the post_validate method or listening to the corresponding event should work.)

If you try this, bear in mind that post_validate is already called while the user is editing (ie on moving focus out of a field).

Inconsecutive answered 30/4, 2011 at 18:11 Comment(0)
S
1

I dont't know if it's best practice, but you can hook up on def at_post_create_script from base object on creation and manage_beforeDelete on delete.

for example:

from Products.ATContentTypes.lib import constraintypes

class YourContentype(folder.ATFolder)
[...]

    def at_post_create(self):
        origin = aq_parent(aq_inner(self))
        origin.setConstrainTypesMode(constraintypes.ENABLED)  # enable constrain types
        org_types = origin.getLocallyAllowedTypes()           # returns an immutable tuple
        new_types = [x for x in org_types if x! = self.portal_type]       # filter tuple into a list
        origin.setLocallyAllowedTypes(new_types)

    def manage_beforeDelete(self, item, container)          
        BaseObject.manage_beforeDelete(self, item, container)     # from baseObject
        self._v_cp_refs = None                                    # from baseObject
        origin = aq_parent(aq_inner(self))
        origin.setConstrainTypesMode(constraintypes.ENABLED)  # enable constrain types
        org_types = origin.getLocallyAllowedTypes()           # returns an immutable tuple
        new_types = [x for x in org_types].append(self.portal_type)
        origin.setLocallyAllowedTypes(new_types)

Note: There is also a method called setImmediatelyAddableTypes(), which you may want to explore. Note II: This does not survive content migration.

Syreetasyria answered 29/4, 2011 at 15:39 Comment(1)
This would restrict it to one object of this type in total instead of one object of this type per user.Fiester

© 2022 - 2024 — McMap. All rights reserved.