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
- Create a filter that implements com.google.common.base.Predicate<Channel>
- 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>