2.6.
Permissions and startup modules - Take 2
Up one level
Handling permissions for several content types
There is a better, advanced way to write this code so that it still works even if you define several content types (in the content subpackage). This technique, introduced by Ben Saller in his "Bricolite" example product (which you can find in the Collective SVN), is useful to define a dictionary containing several definitions (ADD_CONTENT_PERMISSIONS), making use of Archetypes 'listTypes' function:# Defining several Add permissions
ADD_CONTENT_PERMISSIONS = {}
types = listTypes(PROJECTNAME)
for atype in types:
permission = "%s: Add %s" % (PROJECTNAME, atype['portal_type'])
ADD_CONTENT_PERMISSIONS[atype['portal_type']] = permission
# Assign default roles
setDefaultRoles(permission, ('Owner', 'Manager',))
The developer is encouraged to use this improved code. We need to update the startup module based on it.
Improving the __init__ module
The first change needed here is to import ADD_CONTENT_PERMISSIONS instead of ADD_CONTENT_PERMISSION:from permissions import ADD_CONTENT_PERMISSIONSAgain, thanks to Ben Saller, we have a way to register each content type (which is useful when you later augment your product with additional types) with its own permission:
def initialize(context):
content_types, constructors, ftis = process_types(
listTypes(PROJECTNAME),
PROJECTNAME)
# We want to register each type with its own permission,
# this will afford us greater control during system
# configuration/deployment (credit : Ben Saller)
allTypes = zip(content_types, constructors)
for atype, constructor in allTypes:
kind = "%s: %s" % (PROJECTNAME, atype.portal_type)
utils.ContentInit(
kind,
content_types = (atype,),
permission = ADD_CONTENT_PERMISSIONS[atype.portal_type],
extra_constructors = (constructor,),
fti = ftis,
).initialize(context)
Python notes:
We can use the "ADD_CONTENT_PERMISSIONS[atype.portal_type]" construct because ADD_CONTENT_PERMISSIONS references a dictionary in which the keys are the potential content types names.
The zip() function is a Python built-in that pairs up elements of two lists. In this case, "allTypes" will be a list of tuples containing a content type from "content_types" and the corresponding constructor from "constructors".