How to Add a New Feed Preset in Bonfire
View SourceThis guide walks through the process of adding a new feed preset to Bonfire, using the Events feed as an example.
Overview
Feed presets in Bonfire are pre-configured feed definitions that determine:
- What content is displayed
- Who can access the feed
- How the data is loaded and optimized
- UI presentation and navigation
Step 1: Locate the Configuration File
Feed presets are defined in:
/extensions/bonfire_social/lib/runtime_config.ex
Step 2: Define the Feed Preset
Add your new feed preset to the feed_presets
list in the runtime configuration. Feed presets are defined as a keyword list where the key is the feed's atom identifier.
Basic Structure
your_feed_name: %{
name: l("Display Name"),
built_in: true,
description: l("Description of what this feed shows"),
filters: %FeedFilters{
# Filter configuration
},
icon: "icon-name",
assigns: [
# UI configuration
]
}
Example: Events Feed
events: %{
name: l("Events"),
built_in: true,
description: l("Events and gatherings"),
filters: %FeedFilters{
feed_name: :events,
object_types: ["Event"], # ActivityPub Event type
exclude_activity_types: [:like, :boost, :flag]
},
icon: "ph:calendar-blank-bold",
assigns: [
selected_tab: :events,
page: "events",
page_title: l("Events"),
feedback_title: l("No events found"),
feedback_message: l("There are no upcoming events to show. Events from other federated platforms like Mobilizon will appear here.")
]
}
Step 3: Configure Feed Filters
The FeedFilters
struct accepts various filtering options:
Common Filter Options
feed_name
: Internal identifier for the feed (typically matches the preset key)activity_types
: Include only these activity types (e.g.,[:create, :like, :boost]
)exclude_activity_types
: Exclude these activity typesobject_types
: Filter by object type (e.g.,[:post]
,["Event"]
)exclude_object_types
: Exclude specific object typessubjects
: Filter by who performed the activityobjects
: Filter by what was acted uponcreators
: Filter by content creatorsmedia_types
: Filter by media type (e.g.,["image", "video"]
)origin
: Filter by origin (:local
or:remote
)tags
: Filter by hashtagstime_limit
: Limit to content from last N dayssort_by
: Sort order (e.g.,:num_replies
)sort_order
::asc
or:desc
Example Configurations
# Media-specific feed
images: %{
filters: %FeedFilters{
media_types: ["image"]
}
}
# Local content only
local_posts: %{
filters: %FeedFilters{
origin: :local,
object_types: [:post]
}
}
# User-specific activities
user_activities: %{
filters: %FeedFilters{
exclude_activity_types: [:like, :follow]
},
parameterized: %{subjects: [:by]}
}
Step 4: Set Permissions
Configure who can access the feed:
current_user_required: true
: Requires user to be logged ininstance_permission_required: :permission_name
: Requires specific permission (e.g.,:mediate
)exclude_from_nav: true
: Hide from navigation menusopts: [include_flags: true]
: Additional permission options
Step 5: Configure UI Settings
The assigns
list contains UI-specific settings:
assigns: [
selected_tab: :your_tab, # Tab identifier
page: "your_page", # Page route
page_title: l("Page Title"), # Page header
feed_title: l("Feed Title"), # Feed section title
feedback_title: l("Empty Title"), # Empty state title
feedback_message: l("Empty msg"), # Empty state message
hide_filters: true, # Hide filter UI
showing_within: :context, # Display context
no_header: true # Hide header
]
Step 6: Add Preload Rules (Optional but Recommended)
Optimize data loading by adding specific preload rules for your feed. Find the preload_rules
configuration section and add:
"Your Feed Name" => %{
match: %{feed_name: :your_feed},
include: [:with_object_more, :tags, :maybe_sensitive_for_me],
exclude: [:with_parent, :notifications_object_creator]
}
Common Preload Options
Include options:
:with_subject
- Load activity subject (who performed action):with_creator
- Load object creator:with_object_more
- Load object with profile/character data:with_media
- Load media attachments:with_reply_to
- Load replied-to content:with_seen
- Add seen/unseen status:tags
- Load tags/categories:emoji
- Load emoji reactions:sensitivity
- Load content warnings:activity_name
- Load activity display names
Exclude options:
:with_parent
- Skip parent relationships:notifications_object_creator
- Skip creator notifications:with_object_peered
- Skip federation data
Step 7: Format and Test
Run the formatter:
mix format extensions/bonfire_social/lib/runtime_config.ex
Restart your Bonfire server to load the new configuration
Test accessing your feed:
- Via UI navigation (if not excluded from nav)
- Via direct URL:
/feed/your_feed_name
- Via API/GraphQL queries
Advanced Features
Parameterized Feeds
For dynamic feeds that accept parameters:
hashtag: %{
built_in: true,
description: "Activities with a specific hashtag",
filters: %FeedFilters{},
parameterized: %{tags: [:tags]}
}
Custom Query Functions
For complex queries, specify a custom base query:
bookmarks: %{
base_query_fun: &Bonfire.Social.Bookmarks.base_query/0,
# ... other config
}
Special Feed Types
Some feeds bypass standard patterns:
curated: %{
# Uses custom query via Pins.list_instance_pins
filters: %FeedFilters{feed_name: :curated}
}
Common Feed Preset Patterns
1. Activity-Based Feeds
Query activities through the Activity table:
notifications: %{
filters: %FeedFilters{
feed_name: :notifications,
show_objects_only_once: false
}
}
2. Edge-Based Feeds
Query relationships directly through the Edge table:
my_flags: %{
filters: %FeedFilters{
activity_types: [:flag]
},
parameterized: %{subjects: [:me]}
}
3. Media Feeds
Filter by media content:
videos: %{
filters: %FeedFilters{
media_types: ["video"]
}
}
4. User-Specific Feeds
Require authentication and filter by current user:
my_events: %{
current_user_required: true,
parameterized: %{subjects: [:me]}
}
Troubleshooting
- Feed not appearing: Check permissions and
exclude_from_nav
setting - No data loading: Verify filter configuration matches existing data
- Performance issues: Add appropriate preload rules
- Permission errors: Verify
current_user_required
and permission settings
Next Steps
After adding a feed preset:
- Consider adding UI components if needed
- Add tests for the new feed
- Document the feed in user-facing documentation
- Consider internationalization for all user-visible strings