Override viewlet to be less pervasive - plone

I'm using a 3rd party product that provides a viewlet with an overly pervasive context of plone.uuid.interfaces.IUUIDAware, so it's effectively appearing on everything. I'd like to override this to restrict it to specific content types on my site.
I've tried adding the following declarative to both configures.zcml and overrides.zcml in the site package:
<browser:viewlet
name="other.product.viewlet"
for="my.site.interfaces.ICustomContentType"
manager="plone.app.layout.viewlets.interfaces.IAboveContentBody"
class="other.product.ViewletClass"
template="browser/copy_of_product_viewlet.pt"
layer="my.site.interfaces.ISiteLayerMarker"
permission="zope2.View"
/>
However, it doesn't seem to replace the one provided by the product (I'm not sure how to refer to the template in the product from the site package override, so made a local copy).

Use a convenient configure.zcml instead of overrides.zcml and add the layer-attribute to bind the viewlet to your product's interface.
See also:
http://developer.plone.org/views/more_view_examples.html

Related

Create dynamic stylesheet

I need to allow the webmaster of a plone site to change the "main color" of the site (repercuted on the docuemntFirstHeading, portletHeader, etc).
I think I can use the base_properties.prop file liked to a mystylesheet.css.dtml file.
Is there a way to modifiy programmaticaly the base_properties file (which would repercute the changes in mystylesheet.css.dtml with a "&dtml-maincolor" declaration) ?
I'm using Plone 4.3.3
There was a product for Plone 3 called CSSManager which provided a form to edit the base_properties. It may need some updating of imports to work in Plone 4; Plone 4's default "sunburst" theme does not use base_properties, so there probably hasn't been much motivation for that basic maintenance to happen.
Maybe you can look at its code to find out how to edit base_properties.
https://pypi.python.org/pypi/Products.CSSManager
You can have a look at the stylesheet in adi.slickstyle (disclaimer: one of my humble packages), which collects and unifies all selectors setting col, bg-col and borders, so they can be set at once.
If you want to give a user access to a customizable stylesheet via a Plonesite's UI (=not ZMI), check out adi.ttw_styles (disclaimer: yet another one of my humble packages) it allows to use a 'page'-contenttype as the stylesource, thus you can grant edit-permission to any user you want, easily via the sharing-tab of the page.
The future: Plone 5 is said to introduce LESS based styles, to address this and make base_properties obsolete.

How do I sub classing a layer to overide an already overriden page template by jbot?

Similar to the problem in this question (How can I override an already overriden template by jbot?) I am using a base skin that contains jbot overides to template files that I want to overide again.
My product is based on a theme called responsive theme. This theme contains overrides I wish to change.
skins.xml:
<skin-path name="buyspoke-theme" based-on="Responsive Theme">
configure.zcml
<browser:jbot
directory="templates"
layer=".browser.interfaces.IThemeSpecific" />
the jbot overrides in 'responsive theme' are taking priority. I realize from the question above the solution is to 'subclass a layer', I suppose my question is how? An idiot guide would be much appreciated.
You must provide another jbot registration in another product:
<browser:jbot
directory="templates"
layer=".your.product.CustomInterface" />
Then your interface must be something like this:
from .... import IThemeSpecific
class CustomInterface(IThemeSpecific):
pass
And you must register a browser layer for you product.
So: your new interface is subclassing the interface from the theme.
Another way is to use z3c.unconfigure.
Note: I fear that both ways will replace all of the templates inside the original folder (so I think you can't simply customize a single template).

How to customize dexterity-through-the-web-content view?

I created a content in my Plone 4.3 site (no grok here) with the very nice Dexterity through-the-web editor. Now I'd like to customize the default view for this content.
I've read Martn Aspelli's book but the problem is that through-the-web content does'nt have a specific interface (so I can't use it to create my specific view).
If you want to do this all through-the-web, then do the following:
Create a template for your view in the "custom" folder of
portal_skins (through the ZMI). You'll probably want to start with a
copy of something like the page template
(portal_skins/plone_content/document_view). Give it a name like
your_content_type_view. Test it by appending /your_content_type_view
to the URL for a sample object.
Edit the Factory Type Information (portal_types/your_content_type/Default
view method) to be your_content_type_view.
What you will have done is create a skin-level view for the type. This is different from the browser views that Martin is discussing, which do indeed require a class. The Dexterity development team is working on a way to provide TTW maintenance of browser views, but that's for a later version of Plone.
Meanwhile, if you later transfer your Dexterity content type to a Python add on, you'll be able to use your template, possibly unmodified for a browser view.

how to make Plone Dexterity container look like Archetypes folder

I've created a Dexterity product that includes container and non-container Dexterity content types. Having discovered collective.documentviewer (yay! thanks! huzzah!), I'd like to use its dvpdf-group-view, but that is registered in ZCML as being for Folders, and my Dexterity containers don't qualify. I've looked through the web interfaces available on my container type, added SiteRoot, and that enabled the view to be applied, but is also completely wrong.
I'm confident there's a right way to do this, and I'm pretty sure it's central to the whole adapter/interface mechanism, but I just can't find it in any of the books.
Anyone care to try an explanation? First, the line or two that would enable a Dexterity container to pretend it's also a Folder; second, how to change the default view of a single instance of a Dexterity type so that it presents a foreign component's view?
Thanks.
1. Register the view for dexterity containers too
The view is registered for the Archetypes folder interface (Products.CMFCore.interfaces._content.IFolderish), but your dexterity container does not provide this interface (but plone.dexterity.interfaces.IDexterityContainer).
The reason may be that the product and/or the view is not compatible with dexterity.
Anway, you can try it out yourself by registering the view also for the the IDexterityContainer interface by putting a little ZCML in the configure.zcml in your package (see also the Creating a package section of the Dexterity Developer Manual):
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<configure package="collective.documentviewer">
<browser:page
name="dvpdf-group-view"
for="plone.dexterity.interfaces.IDexterityContainer"
class=".views.GroupView"
template="templates/group-view.pt"
permission="zope2.View"
layer=".interfaces.ILayer" />
</configure>
</configure>
The <browser:page> is copied from the collective.documentviewer configure.zcml but I've changed the interface for= to the dexterity container interface, so that the view also works for dexterity containers.
The inner <configure package="collective.documentviewer"> tells the ZCML parser that the configuration should be applied as if the configure.zcml would be directly in collective.documentviewer - this allows you for example to use the original template (otherwise you would have to copy it or do some nasty things).
I did not test it myself: it may still be that the view needs an archetypes container and does not work with a dexterity container. It may also be that you have to register more components from the documentviewer for dexterity containers (maybe the menus? take a look at what is registered in the original configure.zcml.
If everything works well you should consider doing the changes in collective.documentviewer on github directly and make a pull-request to the author (be aware that dexterity is not plone-core yet). But first ask if and how you should do it :-)
2. Changing the default view
With plone it is possible to define multiple views for a specific type. The view can then be selected in the display menu per instance of this type. If you open up http://localhost:8080/Plone/portal_types/manage_main and click on your type, there is a field Available view methods, where you can add the view-name (dvpdf-group-view) on a seperate line.
After you create a new object of your type or visit an existing one, you have a "Display"-menu which should list the view. Select it and this object now has this view as default.
(If you want to make the view not selectable on other objects of this type you could just remove it from the type configuration so that it is not selectable anymore - the existing configuration of your object will stay).

Recommended approach for marking a dexterity content type with a new interface

While working on a dexterity based project I needed one of my content types to support collective.quickupload by marking it with the IQuickUploadCapable interface.
What I'm currently doing is adding an 'implements' to my configure.zcml file:
`<class class="plone.dexterity.content.Container">
<implements interface="collective.quickupload.browser.interfaces.IQuickUploadCapable" />
</class>`
Since my content type is a Container this works however my first inclination was to use a grok style approach instead of declaring it in ZCML. What's the grok/dexterity way to tell my dexterity content type that it implements an additional interface, or should I stick to the current approach?
Also I tried adding the interface as a behaviour in my profiles/default/types/my.dexterity.content.xml file but this didn't work (I didn't really expect it to as behaviours serve a different purpose).
Sean's answer is good. The other way is to create a behaviour and apply that. You need to register the behaviour with:
<plone:behavior
title="Quickupload"
provides="collective.quickupload.browser.interfaces.IQuickUploadCapable"
/>
You can then add 'collective.quickupload.browser.interfaces.IQuickUploadCapable' to your list of behaviours in the FTI.
Your approach using is not good because it means all Container-based Dexterity types get the marker interface, not just your type.
Why not just subclass IQuickUploadCapable as a mixin after form.Schema in your type interface?
You can not use it as a behaviour because it doesn't claim to be used in that way.
As I read from pypi, is intended to be used in a portlet or in a viewlet.
To add it in a grok style you should:
from collective.quickupload.browser.interfaces import IQuickUploadCapable
from plone.directives import form
class IMyContent(form.schema):
grok.implements(IQuickUploadCapable)
And that's it!
Be sure that your content type allows files to be added inside it, so is both folderish and it allows files to be added (or it just doesn't restrict to any specific content type).

Resources