I've had more than my fair share of pain trying to get my viewlets to go where they're supposed to go, and to hide or show them as needed. This tutorial by David Convent is great, but there are a few additional points that might help some folks: http://plone.org/documentation/tutorial/customizing-main-template-viewlets/overriding-a-viewlet.
Let's look at this code for a second:
‹?xml version="1.0"?›
‹object›
‹order manager="plone.portaltop" skinname="Dogwood Theme" based-on="Plone Default"›
‹viewlet name="plone.path_bar"/›
‹/order›
‹hidden manager="plone.portaltop" skinname="Plone Default"›
‹viewlet name="plone.path_bar" /›
‹/hidden›
‹/object›
My goal is to hide the default Plone breadcrumbs and replace them with my own viewlet, which is customized to have >> instead of an arrow dividing the crumbs.
WHAT CODE GOES HERE?
--------------------
First, in your viewlets.xml, you only want to include the pieces of information that is changing. You don't want to grab the entire CMFPlone/Profiles/viewlets.xml file. That's because we are basing our skin off of Plone Default (or you should be), and it knows that the CMFPlone profile is the base profile. The next section explains how you correctly specify this.
FINER POINTS ABOUT SYNTAX:
--------------------------
Notice that the items I'm showing (order manager) says the name of my skinname, based on Plone Default. Unless you have a good reason not to, you should always specify the skinname and say that it's based on Plone Default.
When I'm hiding viewlets, I am generally hiding Plone default items, not anything from my skin, so the syntax is slightly different between order and hidden managers.
WHAT'S MY SKINNAME?
-------------------
The skinname in viewlets.xml needs to match the one in skins.xml, profiles.zcml, and the configure.zcml file where the IThemeSpecific layer is defined. Considering that there are a lot of pathnames running around, it's easy to get confused. I rely on the skinname that's specified in configure.zcml, where my IThemeSpecific interface is registered, because I know that it's generated automatically by my theme recipe and therefore probably correct.
HOW DO I GET MY CHANGES INTO MY SKIN?
-------------------------------------
Say you've got a highly customized theme. Your theme might even be tied into some additional products, such as a profile product. Things can get a little delicate here, and it becomes increasingly more dangerous to reinstall your theme product to see the changes you expect to see -- especially on a live site! In this case, what you want to do is go to portal_setup in the ZMI, click on the import tab, and select the Profile you wish to import from. THIS STEP IS VERY IMPORTANT. Choose the name of your theme, select the "viewlets" option to import, and import the selected step. Assuming all goes well, your GenericSetup will be re-read, and your viewlets will move accordingly.
WHY IS IT STILL NOT WORKING?
----------------------------
I followed exactly this process, and yet my viewlets were not going where I expected to see them. I wanted my breadcrumbs to display in the portaltop area, but they refused to budge. Upon opening configure.zcml, where my breadcrumbs viewlet was defined, I realized the problem:
‹!-- The breadcrumbs --›
‹browser:viewlet
name="plone.path_bar"
manager="plone.app.layout.viewlets.interfaces.IAboveContentTitle"
layer=".interfaces.IThemeSpecific"
class=".viewlets.PathBarViewlet"
permission="zope2.View"
/›
Do you see it? I had specified the manager as IAboveContentTitle, when I should have made it IPortalTop. Viewlets.xml doesn't *really* control where your viewlet goes. The actual definition happens in configure.zcml (this is what tells Zope that your viewlet exists), but viewlets.xml needs to talk to that file for viewlet ordering / showing to work correctly.
If you changed your ZCML like I did, don't forget to restart your Zope or use plone.reload!
WAIT, IT'S *STILL* NOT WORKING!
-------------------------------
Assuming your viewlets.xml, configure.zcml, and viewlets.py are all correct, only one other thing could be wrong. Usually at this point you've tried to hide / show your viewlet a couple of times, and the GenericSetup is getting a little hairy under the covers.
Unfortunately, removing a viewlet from a manager doesn't unhide it. If you've been trying to hide / unhide a viewlet, it doesn't know how to remove that item from the "hidden" list. I've heard rumors that a "purge" command for GenericSetup would work, but I could never get it to work for me. The answer at this point is, use @@manage-viewlets and use the Show link TTW.
ERRORS TOO?
-----------
Every now and then, I also wind up with a typo in my viewlets.xml. Usually, it's something lame like forgetting to close the ‹/object› tag, and when I import my xml file, I get a rather obtuse error:
AttributeError: 'ViewletSettingsStorage' object has no attribute 'getPhysicalPath'
It's scary at first, but once you realize it's saying you have a typo, it becomes easy to resolve.
Whew!