five:protectName error with allowed_interfaces and allowed_attributes - plone

in my browser / configure.zcml I've putted a directive to manage a view with a specific interface and method, in this way:
<browser:page
for="my.package.interfaces.ICartellaBandidiLavoro"
name="lavoroautonomo"
class=".cartellabandiview.cartellabandiView"
template="cartellabandiview.pt"
allowed_interface=".cartellabandiview.ICartellabandiView"
allowed_attributes="rss_bandi"
permission="zope.Public"
/>
in the cartellabandiview.py I have
[...]
class ICartellabandiView(Interface):
""" cartellabandi view interface """
def rss_bandi():
""" rss """
when I start the instance I obtain an error
raise ConfigurationConflictError(conflicts)
zope.configuration.config.ConfigurationConflictError: Conflicting configuration actions
For: ('five:protectName', <class 'Products.Five.metaclass.SimpleViewClass from /Users/vito/repos/my.package/my/package/browser/cartellabandiview.pt'>, u'rss_bandi')
Any suggestions?
Vito

If the code you pasted is right, probably is only an indentation problem. rss_bandi is not a method inside the ICartellaView class. it seems is an external module level function.
As Mathias noted already noted: yes, you only need allowed_interface.

Related

Extending the personal preferences page

I'm attempting to make an add-on that, among other things, adds another option to the personal preferences page. I've tried to piece together how to do this properly from various guides on loosely related topics, but I've had no luck. I'm just getting into Plone development, and a lot of this is somewhat foreign to me, so please be kind :)
I'm doing all this in Plone 4.3
When I have the add-on enabled on the site, it doesn't give me any errors, but the extra field isn't included on the preferences page.
So far, I've got something like this, ignore the odd naming scheme. Again, this was pieced together from other guides, and I wanted to get it working before I refactored.
userdataschema.py
from plone.app.users.browser.personalpreferences import IPersonalPreferences
from zope.interface import Interface
from zope import schema
class IEnhancedUserDataSchema(IPersonalPreferences):
""" Use all the fields from the default user data schema, and add various
extra fields.
"""
buttonsEnabled = schema.Bool(title=u'Transition button widget.',
default=True,
description=u'Uncheck to remove the transition button box from ALL pages.',
required=False
)
adapter.py:
from plone.app.users.browser.personalpreferences import PersonalPreferencesPanelAdapter
from app.statebuttons.userdataschema import IEnhancedUserDataSchema
from zope.interface import implements
class EnhancedUserDataPanelAdapter(PersonalPreferencesPanelAdapter):
"""
"""
implements(IEnhancedUserDataSchema)
def get_buttonEnabled(self):
return self.context.getProperty('buttonsEnabled', '')
def set_buttonsEnabled(self, value):
return self.context.setMemberProperties({'buttonsEnabled': value})
buttonsEnabled = property(get_buttonEnabled, set_buttonsEnabled)
overrides.zcml:
<configure
xmlns="http://namespaces.zope.org/zope"
i18n_domain="collective.examples.userdata">
<adapter
provides=".userdataschema.IEnhancedUserDataSchema"
for="Products.CMFCore.interfaces.ISiteRoot"
factory=".adapter.EnhancedUserDataPanelAdapter"
/>
</configure>
If anyone could give me some input on what I'm doing wrong, that would be awesome. If I'm way off the mark, I'd appreciate some input on where to go next.
You can make your new field show up on ##personal-preferences by adding this to your existing code:
browser/configure.zcml
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<browser:page
for="plone.app.layout.navigation.interfaces.INavigationRoot"
name="personal-preferences"
class=".personalpreferences.CustomPersonalPreferencesPanel"
permission="cmf.SetOwnProperties"
layer="..interfaces.IAppThemeLayer"
/>
</configure>
browser/personalpreferences.py
from plone.app.users.browser.personalpreferences import PersonalPreferencesPanel
from plone.app.users.browser.personalpreferences import LanguageWidget
from plone.app.users.browser.personalpreferences import WysiwygEditorWidget
from zope.formlib import form
from app.statebuttons.userdataschema import IEnhancedUserDataSchema
class CustomPersonalPreferencesPanel(PersonalPreferencesPanel):
form_fields = form.FormFields(IEnhancedUserDataSchema)
# Apply same widget overrides as in the base class
form_fields['language'].custom_widget = LanguageWidget
form_fields['wysiwyg_editor'].custom_widget = WysiwygEditorWidget
Note that you'll need a browser layer IAppThemeLayer registered in profiles/default/browserlayer.xml, and to define storage for your field in profiles/default/memberdata_properties.xml.
You can see why this is necessary in plone.app.users.browser.personalpreferences. IPersonalPreferences is looked up as follows:
class PersonalPreferencesPanel(AccountPanelForm):
...
form_fields = form.FormFields(IPersonalPreferences)
...
The schema is bound to the IPersonalPreferences interface. You have to change the control panel in order to change the looked-up schema.
Instead you could use the IUserDataSchema approach described in https://pypi.python.org/pypi/collective.examples.userdata but as you've seen in order to override ##personal-information you need to use overrides.zcml which is an if-all-else-fails kind of override and not a very welcome citizen in a third party add-on.
Others may disagree but my personal preference (should I say my IPersonalPreference?) for this kind of problem is to create a dedicated form for the setting(s) and link to it from e.g. the personal tools menu.
overwriting personal-preferences should not be necessary.
just follow the documentation on https://pypi.python.org/pypi/plone.app.users
seems you're missing:
a userdatascheaprovider
from plone.app.users.userdataschema import IUserDataSchemaProvider
class UserDataSchemaProvider(object):
implements(IUserDataSchemaProvider)
def getSchema(self):
"""
"""
return IEnhancedUserDataSchema
the GS configuration for it in componentregistry.xml:
a registration of your new field in GS properties.xml to make the field show up on the registration page (optionally)
<object name="site_properties" meta_type="Plone Property Sheet">
<property name="user_registration_fields" type="lines" purge="False">
<element value="yourfield" />
</property>
</object>
to make your field show up in personal preferences follow the documentation on https://pypi.python.org/pypi/plone.app.users/1.1.5
section "How to update the personal information form"

Plone 4.2 formwidget contenttree permissions

I have a dexterity content type in Plone 4.2.4, that uses the contenttree widget to manage referenced objects, but only in the editForm.
I realized, that the referenced items had to be external_visible to get displayed by the widget, which means that anonymous users could View and AccessContentsInformation. Thats not what I wanted. So I dug in the contenttree widget source and added the following to my products browser/configure.zcml
<include package="Products.CMFCore" file="permissions.zcml"
zcml:condition="installed plone.app.upgrade" />
<browser:page
for="*"
name="contenttree-fetch"
class="my.product.content.bikemetamodel.EditForm"
permission="cmf.ModifyPortalContent"
/>
<adapter factory="my.product.browser.widgets.MetamodellContenttreeAdapter" />
and an adapter
class MetamodellContenttreeAdapter(object):
implements(IBikeMetaModel)
adapts(Interface)
def __init__(self, context):
self.context = context
def _get_allowed_modeltypes(self):
return None
def _set_allowed_modeltypes(self, value):
print "setting", value
allowed_modeltypes = property(_get_allowed_modeltypes, _set_allowed_modeltypes)
[...]
But this seems to be not enough. The underlying catalog search returns no result, If the permissions are set to deny View and AccessContentsInformation to anonymous users. So I guess, I must use the view permission to construct some kind of proxy user.
Would it be ok, to use a SecurityManager in the newly created view to fetch the results as a different user? Or am I just missing something?
Ok, here is how I solved the mystery.
After digging around a while, I realized, that I missed the point with my previous idea to override the ##contenttree-fetch view. The solution I came up with is quite simple and seems elegant (enough) for me. I do a sudo style sidestep now, to gather the required items.
Class EditForm(dexterity.EditForm):
grok.context(IBikeMetaModel)
# If it would be another than the edit view, we could manage
# permisssions here. Not neccessary in edit view, because the
# edit permission defined in this content types *.xml counts
# grok.require("cmf.ModifyPortalContent")
#property
def acl_users(self):
return getToolByName(getSite(), 'acl_users')
def updateWidgets(self):
# This is the magic. A sudo style sidestep to a user
# with the id "system" that has permission to gather
# the required lists in the updateWidgets function of
# the base class
proxy_user = self.acl_users.getUserById("system")
oUser = getSecurityManager()
newSecurityManager(self.request, proxy_user)
super(EditForm, self).updateWidgets()
# custom widget updates
self.widgets['title'].mode = DISPLAY_MODE
self.widgets['year'].mode = HIDDEN_MODE
self.widgets['brand'].mode = HIDDEN_MODE
self.widgets['model'].mode = HIDDEN_MODE
# Very Important! Switch back to the original user.
setSecurityManager(oUser)

Can not activate discussions on Plone Dexterity types (folderish)

I have been working on a dexterity based plone application.
I have created a couple of new types. This is what I did to activate comments on a specific dexterity content type named "activity_report":
In Plone Control Panel
In the Discussion section I enabled the following:
globally enable comments
enable anonymous comments
In the Types Section
I chose the "Activity Report" type from the drop down and enabled the "Allow comments" option.
On the file system
In the FTI file activityreport.xml:
<property name="allow_discussion">True</property>
I have restarted the instance and even reinstalled the product, but I can not activate the comments section in the dexterity type.
It is worth mentioning that a standard type (ex. Page) can have the discussion module activated.
Is there something I am missing?
plone.app.discussion currently disables commenting for all containers (see https://dev.plone.org/ticket/11245 for discussion).
I used a monkey patch like the following in one project to short-circuit the normal check and make sure that commenting was enabled for my folderish content type:
from Acquisition import aq_inner
from Products.highcountrynews.content.interfaces import IHCNNewsArticle
from plone.app.discussion.conversation import Conversation
old_enabled = Conversation.enabled
def enabled(self):
parent = aq_inner(self.__parent__)
if parent.portal_type == 'my_portal_type':
return True
return old_enabled(self)
Conversation.enabled = enabled
where 'my_portal_type' is, of course, the portal_type you want commenting enabled for.
The David response is not accurate. The class to be monkeypatched is plone.app.discussion.browser.conversation.ConversationView :
from Acquisition import aq_inner
from plone.app.discussion.browser.conversation import ConversationView
old_enabled = ConversationView.enabled
def enabled(self):
parent = aq_inner(self.__parent__)
if parent.portal_type == 'My_type':
return True
return old_enabled(self)
It works for Plone 4.2 at least. However, thanks David for the hint.
As David and Victor already pointed out, you can just override the enable method of the conversation class. I would recommend using the following approach which is a bit cleaner than monkey patching the conversation class:
https://github.com/plone/plone.app.discussion/blob/master/docs/source/howtos/howto_override_enable_conversation.txt
I also added support for dexterity types to plone.app.discussion recently, so as soon as there is a new release you won't need to customize the conversation class any longer:
https://github.com/plone/plone.app.discussion/commit/0e587a7d8536125acdd3bd385e880b60d6aec28e
Note that this method supports commenting ON folderish objects. There is no support to enable/disable commenting for objects INSIDE a folderish object yet.
In case you want to be able to switch on/off commenting with a behavior field/widget:
https://github.com/plone/plone.app.dexterity/commit/0573df4f265a39da9efae44e605e3815729457d7
This will hopefully make it into the next plone.app.dexterity release as well.
I solved in configure.zcml:
<interface interface="Products.CMFPlone.interfaces.INonStructuralFolder" />
<class class="Products.PloneHelpCenter.types.Definition.HelpCenterDefinition">
<implements interface="Products.CMFPlone.interfaces.INonStructuralFolder" />
</class>
UPDATE: this is not a good idea. I had problems with missing Add menu for each content type having this fix.

selector never works on parsley 3.0 framework, so command never gets called

I am trying to use selector(which to filter event when command Object recevind the event, but never get's called!! help here my pieces of code:
Inmy context file:
<MapCommand type="com.pz.events.FolderEvent" selector="folderDelete">
<Command type="com.pz.command.DeleteFolderCommand"/>
</MapCommand>
dipatching event code pieces:
dispatchEvent(new FolderEvent(FolderEvent.FOLDER_DELETED,targetRoot.selectedItem));
MetaTag:
[Event(name="folderDelete",type="com.pz.events.FolderEvent")]
[ManagedEvents("folderCreate,folderDelete,folderOpen,folderClose,folderRelocate")]
The problem probably lies in you configuration file. The type attribute of MapCommand tag is not a message type, but a command type. For messages messageType attribute is used.
So your MXML code should look like this:
<MapCommand messageType="com.pz.events.FolderEvent" selector="folderDelete">
<Command type="com.pz.command.DeleteFolderCommand"/>
</MapCommand>
Or this:
<MapCommand type="com.pz.command.DeleteFolderCommand" messageType="com.pz.events.FolderEvent" selector="folderDelete"/>

Multiple calls to a portlet method in Renderer class

I'm creating a portlet based on Base Portlet.
In the Renderer class, I've defined a method like this :
def myMethod(self):
""" """
logger.info("hou yeah")
....
In the portlet's template I call view/myMethod
In the root site, I add my portlet.
When I go to http://www.example.com/ I see hou yeah one time. Great.
When I go to http://www.example.com/folder1 I see hou yeah twice. Uh ?
When I go to http://www.example.com/folder1/folder2/folder3 I see hou yeah four time. Really ?
Etc...
Is this a normal behavior ?
Is there a way to fix that ?
Thanks.
It is a normal behaviour, I think. you've just to find which transaction was the right one. The others are deleted by zope transactions handling.

Resources