I've created a custom type dexterity, in Plone 4.3.9, called PersonalPage that must be only allowed in a specific folder Members_folder/userfolder .
In his FTI, by default <property name="global_allow">False</property>.
The userfolder is created in Members_folder with the uid of the authenticated user, in Plone 4.3.3:
if homefolder is None:
# create userfolder in members_folder
members_folder.invokeFactory('Folder', user_id)
userfolder = members_folder[user_id]
utils = userfolder.plone_utils
utils.changeOwnershipOf(userfolder, user_id,
1, None)
userfolder.setCreators([user_id])
roles = list(userfolder.get_local_roles_for_userid(user_id))
if 'Owner' not in roles:
roles.append('Owner')
userfolder.manage_setLocalRoles(user_id, roles)
if shasattr(userfolder, 'canSetConstrainTypes'):
userfolder.setConstrainTypesMode(1)
defaultAllowedTypes = userfolder.getLocallyAllowedTypes()
userfolder.setLocallyAllowedTypes(defaultAllowedTypes + ('personalpage',))
defaultAddableTypes = userfolder.getImmediatelyAddableTypes()
userfolder.setImmediatelyAddableTypes(defaultAddableTypes + ('personalpage',))
userfolder.reindexObjectSecurity()
userfolder.reindexObject()
But after running this script the content type PersonalPage doesn't appear in the list of the addable and allowed contents types of the userfolder.
What's wrong with this? Is there another way to allowed a content type addable only for a folder?
The script is not not working because of the global_allow flag.
Plone has 2 level of content type add restriction:
The first one is a global settings: if a content type is not globally allowed it can't be added anywhere until a content type explicitly list it as a possible subtype
The other one is the TTW addable types, that simply limits the set of contents defined above
If you need to limit addable types for a single folder you can define your folder as a new special type, used only once in the site (so keep global_allow true, create one folder, then disable it); finally specify PersonalPage as one of the allowed_types inside it and keep keep your global_allow settings for PersonalPage to False.
Alternatively you can use collective.factorymenu, to modify Plone add menu through the web (is not released yet but is working).
Related
I have a Plone project which I need to fork; sadly, the UID of the temp folder (for Archetypes objects) is used in the code (as a module level variable, at least, not as strings all over the source tree).
When starting with a fresh ZODB - can I create the temp folder and set the UID? Or should I simply change that constant in the new development branch?
You can set the uid for an AT object by...
obj._setUID(uid)
The _setUID method is defined in Products.Archetypes.Referencable Module
For more information you can also check the plone.app.transmogrifier uidupdater section.
I have a permissions problem in Drupal. I want users to be able to create a certain node type, but there are two different paths I need to give them permissions for to let them do this. The type is content created by a module called isbn2node, and there are two ways to make content through it, each with different paths:
?=node/add/isbn2node-book
?=node/add/isbn2node_book/isbn2node
One has an underscore and the other one has a hyphen. The first path leads to a form that lets users enter information on a book manually; the second path lets them enter an ISBN, searches for it, and populates the form for them based on the results.
I've changed permissions in the People menu so they can add isbn2node-book content manually using the first path, but there isn't an option to let them use the second method. Aliasing the url so it didn't have node/add in the path didn't work either.
Creating a duplicate content type seems like an ugly solution to this; is there a more elegant way to let users access that second path?
A little code in a custom module using hook_node_access should do it.
$node is either a node object or the machine name of the content type on which to perform the access check (if the node is being created then the $node object is not available so it will be a string instead).
So this should do it:
function MY_MODULE_node_access($node, $op, $account) {
if ($op == 'create') {
$type = $node;
if($type == 'book' && $account->uid) return NODE_ACCESS_ALLOW;
}
}
I figured this out, and the issues I was having were specific to this content type. The ISBN2Node module requires users to have the Administer Nodes permission to use its lookup and bulk import features.
There is some extra code for the module's hook_permission and hook_menu sections submitted as a fix in the module's issues thread.
I am customizing Plone Archetypes content type by overriding Schemata() method to have vocabulary contents dynamically:
def Schemata(self):
""" Overrides field definitions in fly.
"""
# XXX: Cache this method?
schemata = getSchemata(self).copy()
settings = self.getResearchSettings()
for row in settings.getFieldCustomizations():
name = row.get("fieldName", None)
vocab = row.get("vocabToUse", None)
field = schemata.get(name, None)
if field and vocab:
# Modify field copy ion
field.vocabulery = vocab
return schemata
Do I need to use cache decorator for Schemata() function or is Archetypes handling Schemata() internally so smart so that it calls it only once per request?
Plone 4.0.
forgot Schemata... you should not touch that stuff.
you can have dynamic vocabularies using object methods or zope vocabularies.
first hit on google
You definitely want to cache the results of Schema() and Schemata(), as at least Schema() is called multiple times during the same request.
I have been trying to create a page using views that will list down all the nodes authored by a specific user.
The user name will be specified in the path (like - stuff/[user-name] )
Can someone please tell me how to do this using Views.
I am stuck on a dead end
for the views url path specify: stuff/%
in the arguments section add: user -> user: name
Should do it, but I'm not sure if it isn't buggy (see this issue: http://drupal.org/node/744468)
If you use user:id instead of username, you will be fine.
I've got a Drupal site which uses a custom field for a certain type of node (person_id) which corresponds to a particular user. I want to create a view so that when logged in, a user can see a list of nodes 'tagged' with their person_id. I've got the view working fine, with a url of my-library/username but replacing username with a different username shows a list of all nodes tagged with that user. What I want to do is stop users changing the URL and seeing other users' tagged nodes. How can I do this? Is there somewhere where I can dictate that the only valid argument for this page is the one that corresponds with the current logged in user's username?
person_id = uid?
In this case, add argument with user:uid, then in Validation options select PHP Code, read comment of this field carefully:
Enter PHP code that returns TRUE or
FALSE. No return is the same as FALSE,
so be SURE to return something if you
do not want to declare the argument
invalid. Do not use . The
argument to validate will be
"$argument" and the view will be
"$view". You may change the argument
by setting "$handler->argument".
Add this code:
global $user;
$account = user_load('name'=>arg(1));
$handler->argument = $user->uid;
return $account->uid == $user->uid;
I'm not sure how you have setup your view, which gives some different options to solve this. A way that should work would be to set the default argument be the logged users id/username and remove the argument from the url.
Alternatively you could create your own filter which requires some work with the views API, but gives more control.