Hide viewlet in specific location/folders

Hi,

we are running Plone 5.2.0 using Python 3.6.8. Our customer wants to disable the web analytics viewlet (plone.analytics) in specific folders which should not be tracked. Using the @@manage-viewlets view I can show and hide that specific viewlet but changes to it are applied to the entire page instead and not only to the folder where I open the viewlet manager.

How could I easily hide that specific viewlet or every other viewlet in the folder /Members and all its subfolders?

If you have your own Plone theme (using Diazo), add a Diazo rule to filter out the markup from the HTML before delivery.

Otherwise custom the related viewlet template (using z3c.jbot) from inside your own policy package and add some additional markup to make the rendering of the analytics code conditional based on your requirements.

My (very) personal opinion:

I would make a new viewlet with a condition and put the javascript there.

Maybe you could have a setting on folders, a bool field: 'do not use analytics'. and check for this, maybe something like this:

<script tal:condition="context/my_show_analytics_check">
.... google analytics script here
</script>

If it is just in members folder you could probably use rules.xml or edit the analytics viewlet

… or maybe do it in analytics.google.com (?)

better to use Diazo, this continuos check can be a penalty for performances.

Other option is to define another viewlet with the same name plone.analytics and applied only on a marker interface. The viewlet would have an empty template and then all folders and object with that marker interface will have this empty viewlet instead of the plone.analytics.

this is a pratical example. In your code you need to just copy the definition you find in plone.analytics for the browser view, adding the marker interface:

layer="..interfaces.IExamplePolicy"

but being plone.analytics useful also for other use cases, better envelope the analytics code you want to delete with a special div, and the use diazo to strip it on particular location.

Wow. I didn't expect it to be so complicated. I thought there is a dedicated function to hide viewlets within a given context I was not aware of.

At the moment it does not need to be user configurable, so I will try to to it with some Diazo rules although I never used them up to now. But maybe my colleague can help me with that.

Any chance to also make this work on Plone 4.3.3 with Python 2.7? Because we also have to change it on an older webpage. I can not remember that there was a point in the configuration to edit the theme within the browser.

Wow. I didn't expect it to be so complicated. I thought there is a dedicated function to hide viewlets within a given context I was not aware of.

Ehm.......... Not to troll, but this sounds a bit like "if there isn't already a switch or field that implements the exact extra functionality I require, it is complicated".

This is both a user,integrator and developer forum so you will get different kinds of suggestions on different levels. If it's not already in "Plone the product" you will have to do some modifications in "Plone the framework".

Viewlets are the lower level workhorses of small code/template snippets, they have no 'user' exposed controls except for the deveoper oriented @@manage-viewlets. Portlets (loved and despised) are editor friendly 'super viewlets with local data' with lots of UI that you can configure.

To control viewlets like the analytics viewlet from inside Plone you will have to do a bit of Python programming to enable/disable them and with Python you have full low level control over the inputs like context, request, whatever.

If your 5.2 website has a Diazo Theme then you can avoid messing with the interna of the CMS as Diazo is working at the end of the pipeline on the generated html from the App Server just before it is delivered to the browser.

But Diazo has only been part of Core Plone since Plone 5, It was optional in Plone 4.

In the Diazo rules you could add a:

The tricky part with Diazo rules is that you have to account for the order they are executed from the rules.xml in your Diazo theme. 'drop' is executed early in the process and one of the default rules in most themes is to copy the whole footer from content to theme and you can only copy one subtree of html once. See https://docs.diazo.org.

You could drop the analytics html for certain paths from the content, or alternatively you remove the html with the css:selector from the theme's index.html . It's difficult to give advice as I have no clue if you use default Barceloneta or a custom theme and how it is set up.

being it javascript, just do it in javascript and load the analytics code based on url.

Sorry, I never wanted to sound like this.

I have no problem with implementing something. That's why I am here. But there is still a lot to learn. It's easy to implement new things but it's hard to find the right documentation when I want to change something what already exists in Plone. Overriding existing functionality or working with that overwhelming amounts of Interfaces and what you can do with it, sometimes let's my brain explode. :smiley:

It is no one to blame except me who went in this topic with the wrong expectations and too less understanding of the possibilities with viewlets. Speaking of that. Back to topic:

It looks like the tricky part is that Plone 4 site where I can not use Diazo. I will try to override the page template for the plone.analytics viewlet within the configure.zcml in our package and then create a hard written logic using tal-expressions or so. It's not beautiful but it will work and for this old project it's okay.

Thank you all for your ideas!

just do a check in javascript in the analytics textarea, something like:

if ( !window.location.href.includes("myhiddenpath") {
analytics code already in the form
}

plone.analytics usually is the place also for other "on the fly" javascript snippets. zcml overriding will just exclude all of them, not only analytics code.

This seems to be the simplest idea of all. If this is okay for our customer maybe we could use that.

I have to correct myself: Diazo was already 'packaged' with Plone 4, but not installed by default. The 'default' portal_skins based Sunburst Plone 4 theme is not using Diazo.
You could activate Diazo in Plone 4 and create a theme which then 'post processes' the already themed output further to change the analytics.viewlet but that would be a waste of resources per page view and development and customisation. If your Plone 4 project already has a custom developped theme using Diazo (early adopter) it's an option.

It's easy to implement new things but it's hard to find the right documentation when I want to change something what already exists in Plone.

'We the Plone community' have a significant documentation problem. The project is now 19+ years old. Up until Plone 3 and early Plone 4 the technical/deveolper part of the documentation was reasonably up to date and in sync with the preferred way of development, but Plone has been expanded after Plone 3 up until Plone 5 with new extra layers/modules and 'new best practices' without completely removing and breaking with the old functionality.

So we have multiple roads leading to Rome, the official documentation is not 'wrong' but it is overcomplete, wrong in some technical details and there is now so much information in there it is almost impossible to weed out the cruft. No one can be blamed for adding a section of new correct documentation, but it's horribly difficult to prune existing partly outdated docs.

Plone 5.1 and 5.2 are releases where old functionality has been removed from code (Archetypes, portal_skins templates/CMFControllers for login, etc. etc).

The mastering Plone training on training.plone.org is an alternative less overgrown source of documentation which gives a good overview of current 'best' practices. It gradually introduces concepts in short chapters. It is also kept up to date and proofread almost yearly out of necessity because a 'speedy' version of it is run at the Conference.

The javascript solution by @yurj seems to be the most elegant solution and short cut if you're in a hurry. Didn't even think of that, I'm to accustomed into jumping to Python solutions first :open_mouth:

Sorry for bringing up this old thread, but my solution is override the render method in the viewlet. For example, i hide the "Related Item Viewlet" only in one view of a Contenttype, in all ohter views the viewlet is available. This can be adapted to a location or another condition.

  <!-- Override the related items viewlet -->
  <browser:viewlet
    name="plone.relateditems"
    manager="plone.app.layout.viewlets.interfaces.IBelowContentBody"
    layer="my.addon.interfaces.IMyAddonLayer"
    class=".viewlets.ContentRelatedItems"
    view="plone.app.layout.globals.interfaces.IViewView"
    permission="zope2.View" />
# viewlets.py
from plone.app.layout.viewlets.content import (
    ContentRelatedItems as BaseContentRelatedItems,
)

class ContentRelatedItems(BaseContentRelatedItems):
    
  @property
  def isEnabled(self):
    context = self.context.aq_inner
    if "tiles_view" in context.getLayout():
      return False
    return True

  def render(self):
    if not self.isEnabled:
      return ""
    return super(ContentRelatedItems, self).render()