Inject content into BuddyPress Activity stream after a certain number of activities
I have seen many people asking this and it seems a common issue. If you want to add extra content or ads in the activity stream after a certain number of entries, this tutorial will help. Thank you @locus for asking it in BuddyDev forums.
Goal:-
Our goal is to add/inject any type of content(most probably banners or ads) in BuddyPress Activity stream after certain number of activity entries repetitively.
We are going to see code samples which may be used to anser following questions:-
- How to inject extra content or ads into BuddyPress Activity stream
- How to add extra entries into BuddyPress Activity stream after certain number of activities repetitively(say custom content after 10 activities).
Solution:-
If you are in a hurry, you can use the following code and modify the value of $n to the number of activity entries after which you want to inject content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * Inject content into BuddyPress Activity stream after 'n' activities. */ function buddydev_inject_content_after_n_activities() { static $current_activity_index = 1; // change $n to the correct number of activities. $n = 5; // After how many activities you want to inject content. if ( $current_activity_index % $n === 0 ) { ?> <li class='activity-item activity-ad-item activity-custom-entry'> Your code snippet ... </li> <?php // show the activity injected content. } // increment the current index. $current_activity_index ++; } add_action( 'bp_after_activity_entry', 'buddydev_inject_content_after_n_activities' ); |
Explanations:-
If you want to understand it in more details and expand upon it, please keep reading.
Basics:-
What we want to achieve:-
The first step is to decide what we want to achieve. For example:-
- Do you want to inject ads in BuddyPress activity stream after 5 or 10 activities?
- Do you want to add a banner in BuddyPress activity stream after 4 or 5 entries?
- Do you want to add any custom html after n number of activities?
There are two things common here.
- You need some kind of content to inject/add. I am assuming you have the html or javascript for the content at your disposal. Let us call in the custom snippet.
- You need to decide when to repeat(or repeat or not?).
For this tutorial, we are going to repeat after a certain number of activities.
How to achieve it?
Once we have decide on what we want, we need to decide how we want to achieve it. As you might have guessed, we need to add our snippet(content) to some template file. There are two possible ways:-
- Modify the template for BuddyPress activity stream and inject the code(I do not prefer this approach)
- Or Inject the code using action hooks
In the first approach, you will need to create/copy/modify buddypress/activity/entry.php or buddypress/activity/activity-loop.php in your theme. Since this is not my preferred way, I am going to skip it. If you want to go this route, Please do post in our forums and we will help.
Adding content via action hooks:-
There are two interesting template hooks(actions) available for us.
1 2 | bp_before_activity_entry bp_after_activity_entry |
- bp_before_activity_entry:- It fires before the activity item entry.
- bp_after_activity_entry:- It fires after the activity item entry.
You can use any of the above hooks. It depends on your choice and thinking(after nth or before nth entry). The before nth entry can be rewritten as after (n-1)th entry. Selecting the hook is not going to make much difference.
I am going with bp_after_activity_entry action.
As soon as we attach a callback(any callable function, method etc) to the action, It will be called after each entry.
Example:- Attaching callback to bp_after_activity_entry action.
1 2 3 4 5 6 7 8 | /** * Calling after each activity entry. */ function buddydev_custom_after_each_activity_entry() { echo "<li>I am called after each activity entry...</li>"; } add_action( 'bp_after_activity_entry', 'buddydev_custom_after_each_activity_entry' ); |
If you add that code to your bp-custom.php or your theme's functions.php, you will see that the content is printed after each activity entry. Good, remove it for now.
It works but it does not solve our issue. Since the action is called for each activity entry, we need to some way to maintain the state(current activity index which can be guessed from the number of times our function got called) and only add our custom code after it matches our repetition criteria.
To maintain the state inside a function, we will be using a static variable. This variable keeps track of how many times the function was called(or how many times the activities entry got printed). Based on it, we add our custom snippet to activity stream.
And that's how our final code from the first section works. Here is the same code again. I hope it makes a lot more sense now.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * Inject content into BuddyPress Activity stream after 'n' activities. */ function buddydev_inject_content_after_n_activities() { static $current_activity_index = 1; // change $n to the correct number of activities. $n = 5; // After how many activities you want to inject content. if ( $current_activity_index % $n === 0 ) { ?> <li class='activity-item activity-ad-item activity-custom-entry'> Your code snippet ... </li> <?php // show the activity injected content. } // increment the current index. $current_activity_index ++; } add_action( 'bp_after_activity_entry', 'buddydev_inject_content_after_n_activities' ); |
I have used list(li element) to keep the markup of activity stream valid. Put your custom code inside the list item.
You can out the code in either your theme's functions.php or in wp-content/plugins/bp-custom.php.
Limitations:-
- Since activity "Load more" is a new request, our function will start from the initial state. It won't consider the number of activity already shown in the stream. For most of the people, that should not be an issue.
- If there are multiple activity loops on a single page, the state(count) will have effects on both.
Enjoy!