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:
- Create a filter that implements java.util.function.BiPredicate<Session,Channel>
- 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 #test 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 test(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 test(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 #test 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.