Removing a portlet from an add-on

We have an add-on that includes a portlet that we're no longer using but we want to remove the code without breaking somebody else site.

so, besides just removing the code I need to create an upgrade step that takes care of removing any portlet assignment on the site that was referring to the current portlet.

following this suggestion I was able to create some code to walk over the site in search of portlets (I realized also that the code was missing the same functionality for the site root).

now I need to be able to identify if a portlet found is the one I need to remove; to do so seems I still need the assignment class; so, my questions are:

  1. how do I identify if a portlet in any given context is the one that I have to remove?
  2. do I need to keep the assignment class in my code for this release, or can I create a dummy class to be removed later?
  3. how do I remove programmatically the portlet definition included on the first place using the portlets.xml file?
  4. how do I deal with portlet managers besides plone.leftcolumn and plone.rightcolumn?

I found some suggestions on this @keul's post but it's still not clear to me.

this is what I have until now:

looks I was able to solve 1 and 2 by leaving some dummy classes (what's the right name for this?) in the code that I plan to remove on next release.

seems to be working as per my manual tests; but I would love to add some integration tests for the upgrade step.

also, the portlet is still addable on the @@manage-portlets form as expected:

Instead of doing it programmatically, I would do it in an "portlets.xml".

"Products.GenericSetup" come with documentation (you must install the source; the "egg" lacks the documentation). In the documentation file "profiles.rst", it speaks about the "remove" attribute to remove items installed by "GenericSetup". The removal can use the same form as the addition - just with an additional "remove" attribute.

Plone's portlets do not much adhere to the "GenericSetup" documentation. But I think, "remove" works.

Likely, portlet managers are registered as local utilities with the portal object. The Zope Component Architecture provides a method to determine all utilities providing a specific interface. This should give you a way to find all portlet managers of a given portal. You could then use the portlet manager api to check whether a given context (user, group, content object) has a given portlet and remove it. It might be costly to check all possible contexts.

I've an analysis about portlet removal in this article (it's old as mummy but probably still applicable):

yes, I know, but that's exactly what I was wanting to avoid: for me it's easier just to use some code instead of having to register a new profile just for that.

anyway, just looking how cryptic the code is, and taking into account that almost everything there starts with an underscore, I think it will be the wiser approach.

yes, I noticed that after running the code: there are many other contexts that I'm not checking and is going to be way too difficult to take care of all corner cases; I'm just not going to do it.

that's the article I referenced above; thanks!

Ops, sorry. I read the post by email, I lost the reference!