Channel Filtering - BloomReach Experience - Open Source CMS
07-01-2019

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 always present and will always be applied. 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). To add a custom channel filter:

  1. Create a filter that implements  java.util.function.BiPredicate<Session,Channel>
  2. Add a Spring bean for your custom filter to  customChannelFilters

ContentBasedChannelFilter code

As an example, we show the default  ContentBasedChannelFilter. The provided Session in the #apply method is the Session of the currently logged-in CMS user.

public class ContentBasedChannelFilter implements BiPredicate<Session, Channel> {

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

    @Override
    public boolean apply(final Session cmsSession, final Channel channel) {
        try {
            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 (contrived example) 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. You need to take the following steps:

Create ChannelNodeBasedFilter

public class ChannelNodeBasedFilter implements BiPredicate<Session, Channel> {

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

    @Override
    public boolean apply(final Session cmsSession, final Channel channel) {
        try {
            if (cmsSession.nodeExists(channel.getChannelPath())) {
                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 

Below  

site/components/src/main/resources/META-INF/hst-assembly/overrides

, add the following bean to an XML Spring configuration file (for example to custom-channel-filters.xml):

<!-- 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>

Access the HstRequestContext in a Channel Filter

In a Channel Filter #apply method you can access the HstRequestContext via

HstRequestContext hstRequestContext = RequestContextProvider.get();

If using it, always make sure to do a null check on the hstRequestContext object since the Channel Filters can also be applied to background threads which do not have an HstRequestContext. The hstRequestContext is the request context for the CMS request. When getting the JCR Session via the request context, you'll get the JCR Session for the currently logged-in CMS user.

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?