How to Remove Configlet from "Site Setup - Add-on Configuration" - plone

I'm deprecating a Site Setup add-on configlet. The procedure I'm following is add the remove="true" property to controlpanel.xml
<!-- profiles/default/controlpanel.xml -->
<configlet
title="MyConfiglet" ...
remove="true">
<permission>Manage portal</permission>
</configlet>
and then execute an upgradeStep. I tried with
<!-- upgrades/configure.zcml -->
<genericsetup:upgradeSteps ...>
<genericsetup:upgradeDepends
title="Remove Configlet"
import_steps="plone.app.registry controlpanel"
/>
</genericsetup:upgradeSteps>
But after executing the upgrade step, I still can see the configlet in /##overview-controlpanel.
What am I missing? What do I need to remove the configlet from the control panel?
Thanks.

The process of removing something from Plone involves more or less the same steps you used to add it; in this specific case you have two ways of doing it: programmatically or using Generic Setup.
programmatically
I think this is easier as involves no more than a few lines of code and you can debug in case of problems.
just use the following code on your upgrade step:
def remove_configlet(self):
from plone import api
config_tool = api.portal.get_tool('portal_controlpanel')
configlet_id = 'MyConfigletId'
config_tool.unregisterConfiglet(configlet_id)
using Generic Setup
create a controlpanel.xml file inside the profile you're registering for your upgrade step; this file should contain exactly the same stuff used to add the configlet plus the remove="True" attribute.
you can find a working example of this on the upgrade_10_to_11 profile of Products.TinyMCE:
controlpanel.xml
upgrades.py
<?xml version="1.0"?>
<object name="portal_controlpanel" meta_type="Plone Control Panel Tool"
xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plone.tinymce">
<configlet title="TinyMCE"
action_id="tinymce" appId="TinyMCE"
category="Products"
condition_expr=""
url_expr="string:${portal_url}/portal_tinymce/##tinymce-controlpanel"
visible="True"
i18n:attributes="title"
remove="True">
<permission>Manage portal</permission>
</configlet>
...
</object>
def upgrade_10_to_11(setuptool):
"""Upgrade TinyMCE from 1.0 to 1.1"""
...
# Unregister old js and register new js
setuptool.runAllImportStepsFromProfile('profile-Products.TinyMCE:upgrade_10_to_11')
in case of doubts take a look at Luca Fabbri's excelent blog post on How to make your Plone add-on products uninstall cleanly.

Related

How to add custom metadata field in Asset programatically during the creation of asset

I want to add the custom metadata field in asset during asset creation. I have the referred the documentation for the asset class and asset manager class. I have used the createAsset function to create the asset.
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dam="http://www.day.com/dam/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:mixinTypes="[mix:referenceable]"
jcr:primaryType="dam:Asset"
jcr:uuid="11111111111111111111111">
<jcr:content
dam:relativePath="demo/demo"
jcr:lastModified="{Date}2016-10-12T21:13:27.224+05:30"
jcr:lastModifiedBy="dam-replication-service"
jcr:primaryType="dam:AssetContent">
<metadata
dam:extracted="{Date}2016-10-12T21:13:27.164+05:30"
dam:sha1="17cb9a4ba368ff01951a11c3ca7e3f8348eee59c"
dam:size="{Long}1184"
dc:format="application/demo"
jcr:mixinTypes="[cq:Taggable]"
jcr:primaryType="nt:unstructured"/>
<related jcr:primaryType="nt:unstructured"/>
</jcr:content>
</jcr:root>
This is a demo code. I want add an additional property in metadata say: source="xyz". I have also referred this link Adding additional Metadata field in AEM-DAM.
Can some one please help me.
Thanks in advance.
Not exactly clear what issue you have in adding additional metadata field. There are couple of ways to do this -
Overlay the metadata form and add additional field as explained here
If the source is automatically identifiable you could add a custom process (write your own process step and then add to model) step to update asset workflow - /etc/workflow/models/dam/update_asset.html or write an event listener (process intensive as it will get called multiple times when asset is imported and processed via workflows) which listens to Asset changes and adds the metadata field
Use java Sling You can add like this i hope so:-
session = resource.getResourceResolver().adaptTo(Session.class);
Node node = session.getNode(resource.getPath());
node.setProperty("hpe-un:objec_name", "my text");

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.

add button in show.jspx in a spring roo mvc project

I've created a spring roo project using 'Getting started with spring roo' as a starting point. The project is created in STS using roo 1.1.5. I've added neo4j graph and is able to create nodes with simple edges and create the web-part issuing 'controller all --package ~.web'.
The project is a simple web-app with a Person and Race node and a Participant-edge with start-time, end-time, total-time and race-id. Since the edge Participant is a #RelatedToVia it becomes a #RelationshipEntity and I want to add a button to save Participant.
I found WEB-INF/tags/form/field/table.tagx where the add-, modify-, delete-buttons and friends are defined, ie.:
<c:if test="${update}">
<td class="utilbox">
..
But where do I set the variable update? I've looked through the code that is created by STS, but unable to find it. Pardon if this is obvious.
regards
Claus
Edit:
I found out that WEB-INF/tags/form/show.tagx have the knobs to enable/disable for instance the update-button:
<c:if test="${empty update}">
<c:set var="update" value="true" />
</c:if>
So I will add my new button in this file. The spring framework seems so well laid out. Just have to find the various places.
regards
Claus
The value for update is obtained from attributes you specify when you use the tag created using the tagx.
For an example,
If form:table was used as in a jspx and if the following was set, you will recieve true in your update variable if it was assigned using a directive. However it seems that the true is set as default in the form:table tag within Spring Roo.
If you want to set it to false, when using you have to set the value to the attribute as following.
<form:table update="false" />
If you want to go deeper into this, look in to the table.tagx file you have mentioned you will find the following line which explains it.
<jsp:directive.attribute name="update" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Include 'update' link into table (default true)" />
Cheers.

How do I add stock portlets (from plone.app.portlets) to my custom portlet manager?

Using the documentation on plone.org along with some in the forum, I was able to get a custom portlet manager below my content in Plone 4.0.8. The goal, actually, is to have 4 custom managers below the content arranged like the dashboard.
Anyway, my manager only allows me to add static and collection portlets. After looking around in the code, I found that when the system goes to populate that 'Add new portlet' dropdown, it loops through all of the portlets. Then, it loops through each portlet's 'for_' attribute checking to see if the interfaces are provided by self--my portlet manager.
def getAddablePortletTypes(self):
addable = []
for p in getUtilitiesFor(IPortletType):
# BBB - first condition, because starting with Plone 3.1
#every p[1].for_ should be a list
if not isinstance(p[1].for_, list):
logger.warning("Deprecation Warning ..." % p[1].addview)
if p[1].for_ is None or p[1].for_.providedBy(self):
addable.append(p[1])
elif [i for i in p[1].for_ if i.providedBy(self)]:
addable.append(p[1])
return addable
How do I add my manager's interface to each portlet's 'for_' list of interfaces?
Your comment is probably the best way to do this. The crux here is that portlets themselves are registered to a portlet manager interface, among other interfaces for contexts, layers, etc.. Another way to do this, for example, would be to add additional registrations in your profiles/default/portlets.xml file to your portlet manager interface for each of the portlets you want addable:
<portlet
addview="portlets.News"
title="News"
description="A portlet which can render a listing of recent news"
i18n:attributes="title;
description"
>
<for interface="your.package.IYourPortletManager" />
</portlet>
Your way is probably best, however, since it sounds like you are creating a columnar portlet manager. You could remove IPortletManager from the base classes, however, since IColumn already subclasses it.

How do I use a permission created by config.py and __init__.py (using paster) in browser/configure.zcml for a custom permission?

I'm using paster to create my content types and views. I'm using Plone 3.3.
In my config.py:
ADD_PERMISSIONS = {
# -*- extra stuff goes here -*-
'MyContentType': 'mynamespace.mypackage: Add My Content Type'
}
In my __init__.py:
for atype, constructor in zip(content_types, constructors):
utils.ContentInit('%s: %s' % (config.PROJECTNAME, atype.portal_type),
content_types=(atype, ),
permission=config.ADD_PERMISSIONS[atype.portal_type],
extra_constructors=(constructor,),
).initialize(context)
...and in browser/configure.zcml:
<browser:page
for="*"
name="myview"
class=".myview.MyView"
template="myview.pt"
allowed_interface=".myview.IMyView"
permission="the permissions defined in ADD_PERMISSIONS: what is the name I can put here?"
/>
I know I can create custom permissions using colective.autopermission, but I I already created them using config.py, how can I use them in my configure.zcml?
EDIT: Hum, browser views defined in ZCML use the Zope 3 permission id, but my config.py is using the Zope 2 permission title. I need to use collective.autopermission to create the zope 3 permission id, or can I use another approach (like just creating a permissions.zcml, with title attributes, using the same title provided in ADD_PERMISSIONS dict, because the permissions in zope 2 style are already created so I don't need collective.autopermission)?
You should indeed use collective.autopermission and create a permissions.zcml (and load that in your configure.zcml, or just add the lines in configure.zcml itself) that contains statements like this:
<permission
id="mynamespace.mypackage.AddMyContentType"
title="mynamespace.mypackage: Add My Content Type"
/>
You can pick a different id, but the title needs to be the same as the title you have given in config.py.
EDIT:
Note that Zope2 versions in use in Plone 4.0 or higher have the collective.autopermission patches included so you do not need to use that package anymore; you do still need the permission declaration in zcml of course.
On Plone 3 you do need the collective.autopermission package and you should depend on it in your setup.py and add <include package="collective.autopermission" /> in your zcml before the permissions registration (or use z3c.autoinclude, included in Plone 3.3, to load that zcml automatigically).

Resources