The Bloomreach Feeds Plugin is a powerful extension for Hippo CMS that enables creation of RSS, Atom, and generic web syndication feeds. This guide covers two key features:
- Property Filtering: Filter feed items based on document properties without custom code
- Atom Enrichment: Automatically add document metadata to Atom feeds using custom namespaces
- Configure filters directly in the CMS UI
- Support for exact matches and wildcard patterns
- Case-insensitive matching
- Atom feeds enriched with custom namespace fields
- Full Atom 1.0 specification compliance
- Zero custom code required for basic usage
Filter feed entries by document properties using the CMS UI. Only documents matching your filter criteria will appear in the feed.
When a feed is generated:
- The filtering modifier reads the configured filter property and value from the feed descriptor
- For each document in the query results:
- Evaluates the specified property on the document
- Checks if the value matches the filter criteria
- Excludes entries that don't match
- Returns only the filtered entries
All feed types (RSS 2.0, Atom 1.0, Generic) support property filtering through two fields:
- Filter by Property: The property name to check (e.g.,
status,featured) - Filter by Value: The value to match (supports exact matches and wildcards)
- Create or edit a feed descriptor (RSS, Atom, or Generic)
- Locate the filtering section on the right panel
- Enter the property name in "Filter by Property"
- Enter the filter value in "Filter by Value"
- Save and publish the descriptor
- Generate the feed - only matching entries will be included
Filter Value: published
Matches: published, PUBLISHED, Published, pUbLiShEd
Use * (asterisk) for zero or more characters:
| Pattern | Syntax | Example | Matches |
|---|---|---|---|
| Prefix | value* |
pub* |
"published", "public", "publisher" |
| Suffix | *value |
*lished |
"published", "established", "cherished" |
| Contains | *value* |
*ublish* |
"published", "republished", "publishing" |
| Complex | *value*more |
*pub*ed |
"published", "republished" |
Configuration:
- Filter by Property:
status - Filter by Value:
published
Result: Only documents with status="published" appear (case-insensitive)
Configuration:
- Filter by Property:
featured - Filter by Value:
true
Result: Only featured documents included
Configuration:
- Filter by Property:
status - Filter by Value:
pub*
Result: Includes documents with status: "published", "publishing", "public"
Configuration:
- Filter by Property:
language - Filter by Value:
en*
Result: Includes "en", "en-US", "en-GB", "english"
Configuration:
- Filter by Property:
location - Filter by Value:
*new*
Result: Includes "New York", "New Delhi", "Denver" (case-insensitive)
- Case Sensitivity: Matching is case-insensitive by default
- Missing Properties: Documents without the specified property are excluded
- No Filter: If either filter field is empty/null, no filtering is applied
- Multiple Filters: Each feed supports a single property-value filter pair
If you need more complex filtering (multiple properties, different operators), extend the base modifier:
public class MyCustomRSSModifier extends RSS20PropertyFilteringModifier {
@Override
public void modifyEntry(HstRequestContext context, Item entry, HippoBean bean) {
// Apply custom filtering logic
super.modifyEntry(context, entry, bean);
// Add additional logic here
}
}Register in Spring configuration:
<bean id="customModifier" class="com.example.MyCustomRSSModifier" scope="singleton"/>Atom feeds automatically include document properties as custom namespace fields, enriching the feed with additional document metadata while maintaining full Atom 1.0 specification compliance (RFC 4287).
The Atom 1.0 specification defines a strict set of core elements (title, author, updated, entry ID, content, summary). While adequate for basic feeds, documents typically contain additional useful information:
- introduction - Brief summary/description
- content - Full article body
- location - Geographic location/origin
- author - Custom author metadata
- language - Document language code
- copyright - Copyright/licensing info
- source - Original source
The Atom10EnrichedModifier automatically extracts document properties and adds them as custom namespace fields:
Field Mapping:
introduction → <br-feed:introduction>...</br-feed:introduction>
content → <br-feed:content>...</br-feed:content>
author → <br-feed:author>...</br-feed:author>
location → <br-feed:location>...</br-feed:location>
source → <br-feed:source>...</br-feed:source>
language → <br-feed:language>...</br-feed:language>
copyright → <br-feed:copyright>...</br-feed:copyright>
Per RFC 4287 Section 6 ("Extensibility"):
"Atom consumers MAY ignore any foreign markup in the document they don't understand."
Custom namespace elements are preserved for clients that understand them and transparent to standard Atom readers. This maintains full specification compliance.
No configuration needed! Atom feeds automatically include these enrichment fields if they exist on your documents:
- introduction
- content
- author
- location
- source
- language
- copyright
To customize which fields are included, override the modifier in your Spring configuration:
File: hst-cms-rest.xml or your custom Spring config
<bean id="atomModifier" class="org.bloomreach.forge.feed.api.modifier.Atom10EnrichedModifier" scope="singleton">
<property name="enrichmentFields">
<list>
<value>introduction</value>
<value>content</value>
<value>location</value>
<value>customField1</value>
<value>customField2</value>
</list>
</property>
</bean><?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:br-feed="http://bloomreach-forge.example.org/feed">
<title>News Feed</title>
<entry>
<!-- Standard Atom fields -->
<title>Breaking News</title>
<author><name>John Doe</name></author>
<updated>2024-01-27T10:00:00Z</updated>
<id>urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6</id>
<content>Full article text goes here...</content>
<!-- Custom enrichment fields (extension elements) -->
<br-feed:introduction>Brief summary of the news</br-feed:introduction>
<br-feed:location>Amsterdam, Netherlands</br-feed:location>
<br-feed:source>Internal News Portal</br-feed:source>
<br-feed:language>en</br-feed:language>
<br-feed:copyright>© 2024 Example Corp</br-feed:copyright>
</entry>
</feed>Enrichment uses Java reflection to find getter methods on document beans:
Field name → Getter method → XML element
introduction → getIntroduction() → <br-feed:introduction>...</br-feed:introduction>
customField1 → getCustomField1() → <br-feed:customField1>...</br-feed:customField1>
For a field to be included:
- The bean must have a public getter method (e.g.,
getIntroduction()) - The method must return a non-null value
- The value's
.toString()must produce a non-empty string - The field must be listed in the
enrichmentFieldsconfiguration
If a field is configured but not found on a document:
- Silently skipped - No error is thrown
- Logged at DEBUG level - Check logs if you expect the field to appear
- Feed generation continues - Other fields continue to enrich normally
Only include fields meaningful for feed consumers:
<!-- Good: focused set -->
<list>
<value>introduction</value>
<value>location</value>
</list>
<!-- Avoid: too many fields clutters the feed -->
<list>
<value>introduction</value>
<value>location</value>
<value>internalId</value>
<value>workflowStatus</value>
<value>approvalDate</value>
<!-- 20+ more fields -->
</list>Choose names that clearly communicate their purpose:
✓ introduction (clear: brief summary)
✓ fullContent (clear: complete text)
✗ intro (ambiguous)
✗ data1 (meaningless)
If content fields contain HTML, note that it will be XML-escaped in the Atom feed:
public String getHtmlContent() {
return "<p>Article text with <strong>formatting</strong></p>";
}Feed readers can decode it if they choose.
Verify enriched Atom feeds with various readers:
- Standard readers should ignore unknown namespaces
- Smart readers may recognize and display custom fields
- API consumers can parse custom namespace fields
Both features work together seamlessly:
<bean id="atomModifier" class="org.bloomreach.forge.feed.api.modifier.Atom10EnrichedModifier" scope="singleton">
<property name="enrichmentFields">
<list>
<value>introduction</value>
<value>content</value>
<value>location</value>
</list>
</property>
</bean>
<!-- Configure filter on feed descriptor: -->
<!-- Filter by Property: status -->
<!-- Filter by Value: published -->This will:
- Only include entries where
status == "published"(filtering) - Add introduction, content, and location fields (enrichment)
cd /Users/josephliechty/Desktop/XM/feeds
# Build the entire project
mvn clean install -DskipTests
# Or if you want to run tests:
mvn clean installcd demo/site/components
mvn test -Dtest=PropertyFilterModifierTestExpected output:
[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
-
Create test documents with different property values:
- Document 1: status = "published", featured = "false"
- Document 2: status = "draft", featured = "false"
- Document 3: status = "published", featured = "true"
-
Create feed descriptors:
- Feed 1: No filter (baseline test)
- Feed 2: Filter by status = "published"
- Feed 3: Filter by status = "pub*" (wildcard test)
-
Configure sitemap items to serve the feeds
- Baseline Test: Feed without filter shows all documents
- Exact Match Test: Feed with status="published" shows only 2 items
- Wildcard Test: Feed with status="pub*" shows correct items
- Case Sensitivity Test: Filter "PUBLISHED" matches "published"
- Missing Property Test: Documents without property are excluded
- Atom Enrichment Test: Enrichment fields appear in Atom feed
- Feed Reader Test: Feed loads correctly in multiple readers
- Open feed URL in browser
- Verify XML structure is valid
- Check item count matches expectations
- Load in feed reader (Feedly, NewsBlur, etc.)
- Verify content displays correctly
- For Atom: Verify enrichment fields are present
Symptom: Configured filters but entries still appear in feed
Solutions:
- Verify the property name is correct (case-sensitive)
- Check that the property exists on the documents
- Remember: matching is case-insensitive for values
- If using wildcards, verify the pattern format (e.g.,
pub*notpub%) - Ensure both filter fields are set (leave empty to disable filtering)
Symptom: Filter seems to exclude everything
Solutions:
- Verify the bean has a getter method for the property
- Method name should follow Java naming: property
foo→getFoo() - Check logs for "Property not found" debug messages
Symptom: All entries are filtered out
Solutions:
- Review the filter value - it might not match any documents
- Try filtering by a property that exists on all documents
- Temporarily clear the filter to verify documents are returned
Symptom: Configured enrichment fields don't show up in Atom feed
Diagnosis:
- Check that bean has a public getter method
- Method name must follow pattern:
get<FieldName>()- Field
introduction→ methodgetIntroduction()
- Field
- Check logs for DEBUG messages about field resolution
- Verify field value is not null/empty
Enable Debug Logging:
log4j.logger.org.bloomreach.forge.feed.api.modifier=DEBUG
Symptom: Custom fields appear but namespace prefix is wrong or missing
Cause: Different feed readers handle namespaces differently
Solution: Standard Atom readers ignore unknown namespaces. Specialized readers will properly recognize the custom fields. This is expected behavior per RFC 4287.
Solutions:
- Ensure class names are fully qualified
- Verify package names are correct
- Check that classes are in the classpath
- Review Spring error messages in server logs
Solutions:
- Run
mvn clean install -DskipTeststo download dependencies - Check that all required JARs are present
- Verify package names and imports
- README.md - Project overview and documentation generation
- PROPERTY_FILTERING_GUIDE.md - Detailed filtering documentation (kept for reference)
- ATOM_ENRICHMENT_GUIDE.md - Detailed enrichment documentation (kept for reference)
For issues or questions:
- Check the Troubleshooting section above
- Enable debug logging to see detailed execution flow
- Review server logs for error messages
- Verify content model has required properties
- Test with simpler cases first (single filter, no wildcards)
- Feature: FORGE-325 Implementation
- Filtering: Property-based filtering with wildcard support
- Enrichment: Atom 1.0 with custom namespace fields
- Compatibility: Fully backward compatible, zero breaking changes