Channel Filtering - BloomReach Experience - Open Source CMS

This article covers a Hippo CMS version 10. There's an updated version available that covers our most recent release.

23-09-2015

Channel Filtering

Default filtering

HST supports pluggable filtering on the channels that are visible below the [view] button for a document or in the Channels Perspective for a logged in CMS user. By default, the  ContentBasedChannelFilter is enabled. It filters out all channels that the current CMS user cannot read the content for. For example, if there are three channels with the content roots 

+ content
    + documents
       + intranet
       + extranet
       + management 

and the logged in CMS user has read access to the content of ' intranet' and ' extranet', then he won't see the channel that has ' management' as content root in the Channels Perspective. 

Customize filtering

Channel filtering can be customized or disabled (in effect). When you want to add a custom channel filter, you need to

  1. Create a filter that implements  com.google.common.base.Predicate<Channel>
  2. Add a Spring bean for your custom filter to  customChannelFilters

Also see the worked out example below. If you want to disable the default channel filter, you can add the following Spring bean to your custom Spring configuration at META-INF/hst-assembly/overrides:

<bean id="defaultChannelFilters" class="java.util.ArrayList"/>

The above overrides HST's default channel filters and replaces it with an empty list of filters.

ContentBasedChannelFilter code

As an example, we used the default  ContentBasedChannelFilter. When calling  RequestContextProvider.get().getSession(), you get the JCR Session belonging to the currently logged in CMS user. This is because the filters are configured in the cms-rest module, which gets the JCR Session from the authenticated CMS user. 

public class ContentBasedChannelFilter implements Predicate<Channel> {

    private static final Logger log = LoggerFactory.getLogger(ContentBasedChannelFilter.class);

    @Override
    public boolean apply(final Channel channel) {
        try {
            Session cmsSession = RequestContextProvider.get().getSession();
            if (cmsSession.nodeExists(channel.getContentRoot())) {
                log.debug("Predicate passed for channel '{}' because user has read access on '{}'",
                        new String[]{channel.toString(), cmsSession.getUserID(), channel.getContentRoot()});
                return true;
            }
            log.info("Skipping channel '{}' for user '{}' because she has no read access on '{}'",
                    new String[]{channel.toString(), cmsSession.getUserID(), channel.getContentRoot()});
            return false;
        } catch (RepositoryException e) {
            log.warn("Exception while trying to check channel {}. Skip that channel:", channel.getContentRoot(), e);
            return false;
        }
    }
}

Example of adding a custom filter

Assume you want to add a channel filter such that a channel is only shown in the Channels Perspective, if the CMS user can read the backing configured channel node (below /hst:hst/hst:channels). You need to take the following steps:

Create ChannelNodeBasedFilter

public class ChannelNodeBasedFilter implements Predicate<Channel> {

    private static final Logger log = LoggerFactory.getLogger(ChannelNodeBasedFilter.class);

    @Override
    public boolean apply(final Channel channel) {
        try {
            Session cmsSession = RequestContextProvider.get().getSession();
     String channelPath = "/hst:hst/hst:channels/" + channel.getName();
            if (cmsSession.nodeExists("/hst:hst/hst:channels/" + channel.getName())) {
                log.debug("Predicate passed for channel '{}' because user has read access on '{}'",
                        new String[]{channel.toString(), cmsSession.getUserID(), channelPath});
                return true;
            }
            log.info("Skipping channel '{}' for user '{}' because she has no read access on '{}'",
                    new String[]{channel.toString(), cmsSession.getUserID(), channelPath});
            return false;
        } catch (RepositoryException e) {
            log.warn("Exception while trying to check channel {}. Skip that channel:", channelPath, e);
            return false;
        }
    }
}

Add the ChannelNodeBasedFilter to the customFilters 

In  META-INF/hst-assembly/overrides, add the following bean to an XML Spring configuration file:

<!-- Custom channel filters be added here. -->
<bean id="customChannelFilters" class="org.springframework.beans.factory.config.ListFactoryBean">
  <property name="sourceList">
    <list>
      <bean id="channelNodeBasedFilter" class="org.example.filter.ChannelNodeBasedFilter"/>
    </list>
  </property>
</bean>

 

 

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?