Action Hooks
Free themeReference for the 70 action hooks BuddyX fires, where each one runs, and how to attach your own markup or logic. Requires PHP 8.0+.
BuddyX prefers filters for data customization (see Filters), but it also fires a set of do_action() events at fixed points in the page skeleton, header, content, footer, and its BuddyPress and WooCommerce template overrides. Actions are for genuinely side-effecting work: printing markup, enqueuing an asset conditionally, or triggering a callback at a known render position.
Attach to any hook from your child theme's functions.php or a plugin:
add_action( 'buddyx_body_top', 'my_prefix_body_top' );
function my_prefix_body_top() {
// your markup or logic here
}
Rules of the road
- Every hook below is real and extracted from the theme. Do not rely on hooks not listed here.
- The "Fires at" column is the first template location that runs the hook, taken from the theme's hook inventory. Skeleton hooks (head, body, header, footer) live in
header.php/footer.php, so they run on every front-end request; content and entry hooks run wherever the matching template part is loaded. - All
buddyx_*action hooks pass 0 arguments. Read request state with WordPress conditionals (is_singular(),is_archive(),is_buddypress()) inside your callback instead. - BuddyX loads its templates with standard
get_template_part(), so you can also override any template part by copying the file into your child theme at the same relative path. Hooks are the lighter-touch option when you only need to inject at a point, not rewrite the markup.
Document and body
Structural hooks that bracket <head>, the opening <body>, and the outer page wrapper. These fire on every page, which makes them the right place for site-wide analytics, banners, skip links, or wrapper markup.
| Hook | Args | Fires at |
|---|---|---|
buddyx_head_top |
0 | header.php:18 |
buddyx_head_bottom |
0 | header.php:24 |
buddyx_wp_body_open |
0 | inc/wordpress-shims.php:18 |
buddyx_body_top |
0 | header.php:30 |
buddyx_page_top |
0 | header.php:35 |
buddyx_page_bottom |
0 | footer.php:51 |
buddyx_body_bottom |
0 | footer.php:57 |
buddyx_wp_body_open is a compatibility shim that runs alongside core wp_body_open; use core wp_body_open for portable code and this only for BuddyX-specific placement.
Header
Wrap or extend the site header and its action area. buddyx_header_actions is the cluster next to the header (search toggle, cart, account); buddyx_mobile_menu_actions is its mobile-menu counterpart.
| Hook | Args | Fires at |
|---|---|---|
buddyx_header_before |
0 | header.php:38 |
buddyx_header_after |
0 | header.php:54 |
buddyx_header_actions |
0 | inc/extra.php:266 |
buddyx_mobile_menu_actions |
0 | template-parts/header/navigation.php:119 |
buddyx_sub_header |
0 | index.php:40 |
Content and entry
Injection points around the main content column, the sidebar, and individual post entries. Use these for content-adjacent widgets, per-post metadata, ad slots, or author bios.
| Hook | Args | Fires at |
|---|---|---|
buddyx_before_content |
0 | 404.php:17 |
buddyx_after_content |
0 | 404.php:25 |
buddyx_entry_before |
0 | template-parts/content/entry-post.php:12 |
buddyx_entry_after |
0 | template-parts/content/entry-post.php:48 |
buddyx_entry_content_before |
0 | template-parts/content-buddypress.php:12 |
buddyx_entry_content_after |
0 | template-parts/content-buddypress.php:48 |
buddyx_sidebar_before |
0 | sidebar-buddypress.php:18 |
buddyx_sidebar_after |
0 | sidebar-buddypress.php:81 |
buddyx_before_content / buddyx_after_content bracket the main content region across templates (the inventory records 404.php as the first occurrence). buddyx_entry_before / buddyx_entry_after run once per post in a loop, so guard against duplicate output if you only want a single instance.
Footer and copyright
Extend the footer widget region and the copyright bar. Pair these with the buddyx_footer_copyright_text filter (see Filters) when you want to change the copyright string itself rather than add around it.
| Hook | Args | Fires at |
|---|---|---|
buddyx_footer_before |
0 | footer.php:22 |
buddyx_footer_after |
0 | footer.php:49 |
buddyx_copyright_before |
0 | template-parts/footer/info.php:12 |
buddyx_copyright_after |
0 | template-parts/footer/info.php:26 |
Breadcrumb
Fire immediately around BuddyX's breadcrumb trail. The inventory records these first in the WooCommerce archive template; they bracket the trail wherever the breadcrumb renders.
| Hook | Args | Fires at |
|---|---|---|
buddyx_before_breadcrumb |
0 | woocommerce/archive-product.php:36 |
buddyx_after_breadcrumb |
0 | woocommerce/archive-product.php:42 |
To change the trail contents rather than wrap it, use the buddyx_breadcrumb_trail_items / buddyx_breadcrumb_trail filters instead.
BuddyPress directory
Theme-owned hooks inside the member and group directory loops, fired just before each avatar. Use them to badge, flag, or annotate directory cards.
| Hook | Args | Fires at |
|---|---|---|
buddyx_before_member_avatar_member_directory |
0 | bb-buddypress/members/members-loop.php:128 |
buddyx_before_group_avatar_group_directory |
0 | bb-buddypress/groups/groups-loop.php:55 |
Integration hooks fired from BuddyX templates
BuddyX overrides a number of BuddyPress, BuddyBoss-style, rtMedia, and WooCommerce templates. Because those overrides preserve the upstream do_action() calls, third-party hooks keep firing from BuddyX's copies. These are not BuddyX-owned hooks; they belong to BuddyPress/rtMedia/WooCommerce and are documented by those projects. Listed here so you know they still run under BuddyX.
BuddyPress and rtMedia
| Hook | Args | Fires at |
|---|---|---|
bb_group_single_top_header_action |
0 | bb-buddypress/groups/single/cover-image-header.php:177 |
bb_group_single_bottom_header_action |
0 | bb-buddypress/groups/single/cover-image-header.php:185 |
bp_before_single_activity_content |
0 | bb-buddypress/activity/single/home.php:31 |
bp_after_single_activity_content |
0 | bb-buddypress/activity/single/home.php:70 |
bp_before_member_body |
0 | rtmedia/main.php:95 |
bp_after_member_body |
0 | rtmedia/main.php:111 |
bp_before_member_media |
0 | rtmedia/main.php:96 |
bp_after_member_media |
0 | rtmedia/main.php:110 |
bp_before_member_home_content |
0 | rtmedia/main.php:276 |
bp_after_member_home_content |
0 | rtmedia/main.php:265 |
bp_member_options_nav |
0 | rtmedia/main.php:298 |
bp_before_group_body |
0 | rtmedia/main.php:181 |
bp_after_group_body |
0 | rtmedia/main.php:220 |
bp_before_group_media |
0 | rtmedia/main.php:182 |
bp_after_group_media |
0 | rtmedia/main.php:219 |
bp_before_group_status_message |
0 | rtmedia/main.php:191 |
bp_after_group_status_message |
0 | rtmedia/main.php:205 |
bp_before_group_home_content |
0 | rtmedia/main.php:338 |
bp_after_group_home_content |
0 | rtmedia/main.php:262 |
bp_group_options_nav |
0 | rtmedia/main.php:360 |
rtmedia_sub_nav |
0 | rtmedia/main.php:102 |
WooCommerce
BuddyX ships styled overrides of the WooCommerce cart, single-product, and shop-archive templates. The standard WooCommerce action hooks fire from these copies, so WooCommerce extensions that hook them continue to work.
| Hook | Args | Fires at |
|---|---|---|
woocommerce_before_main_content |
0 | woocommerce/single-product.php:49 |
woocommerce_after_main_content |
0 | woocommerce/single-product.php:68 |
woocommerce_sidebar |
0 | woocommerce/single-product.php:77 |
woocommerce_before_shop_loop |
0 | woocommerce/archive-product.php:94 |
woocommerce_after_shop_loop |
0 | woocommerce/archive-product.php:118 |
woocommerce_shop_loop |
0 | woocommerce/archive-product.php:105 |
woocommerce_archive_description |
0 | woocommerce/archive-product.php:53 |
woocommerce_no_products_found |
0 | woocommerce/archive-product.php:125 |
woocommerce_before_cart |
0 | woocommerce/cart/cart.php:20 |
woocommerce_after_cart |
0 | woocommerce/cart/cart.php:224 |
woocommerce_before_cart_table |
0 | woocommerce/cart/cart.php:25 |
woocommerce_after_cart_table |
0 | woocommerce/cart/cart.php:203 |
woocommerce_before_cart_contents |
0 | woocommerce/cart/cart.php:39 |
woocommerce_cart_contents |
0 | woocommerce/cart/cart.php:180 |
woocommerce_after_cart_contents |
0 | woocommerce/cart/cart.php:200 |
woocommerce_after_cart_item_name |
2 | woocommerce/cart/cart.php:125 |
woocommerce_cart_actions |
0 | woocommerce/cart/cart.php:194 |
woocommerce_cart_coupon |
0 | woocommerce/cart/cart.php:188 |
woocommerce_after_cart_form |
0 | woocommerce/cart/cart.php:205 |
woocommerce_before_cart_collaterals |
0 | woocommerce/cart/cart.php:207 |
woocommerce_cart_collaterals |
0 | woocommerce/cart/cart.php:218 |
woocommerce_after_cart_item_name is the only action here that passes arguments (the cart item and its cart item key). All others pass 0.
Where are the image, column, and Customizer hooks?
Those extension points exist, but they are filters, not actions - BuddyX exposes them as data you transform rather than events you attach to:
- Featured-image and grid-column sizing:
buddyx_featured_width,buddyx_col_two_width,buddyx_col_three_height, and their siblings. - Customizer registration:
buddyx_customizer_field_args,buddyx_customizer_field_type_map,buddyx_customizer_settings.
See Filters for the full list and examples.
Worked examples
1. Inject an announcement bar at the top of every page
buddyx_body_top runs from header.php on every front-end request, right after the opening <body>.
add_action( 'buddyx_body_top', 'my_prefix_announcement_bar' );
function my_prefix_announcement_bar() {
// Only on the front end, and skip if a dismiss cookie is set.
if ( is_admin() || isset( $_COOKIE['my_announce_dismissed'] ) ) {
return;
}
?>
<div class="my-announcement-bar" role="region" aria-label="<?php esc_attr_e( 'Site announcement', 'my-textdomain' ); ?>">
<?php esc_html_e( 'Free shipping this week only.', 'my-textdomain' ); ?>
</div>
<?php
}
2. Add a call to action after the main content
buddyx_after_content closes the main content region. Guard with a conditional so the block only shows where you want it.
add_action( 'buddyx_after_content', 'my_prefix_post_cta' );
function my_prefix_post_cta() {
if ( ! is_singular( 'post' ) ) {
return;
}
?>
<aside class="my-post-cta">
<h2><?php esc_html_e( 'Enjoyed this article?', 'my-textdomain' ); ?></h2>
<a class="my-post-cta__button" href="<?php echo esc_url( home_url( '/subscribe/' ) ); ?>">
<?php esc_html_e( 'Subscribe for more', 'my-textdomain' ); ?>
</a>
</aside>
<?php
}
3. Append a note to the footer copyright
add_action( 'buddyx_copyright_after', function () {
echo ' <span class="my-footer-note">' . esc_html__( 'Built with care.', 'my-textdomain' ) . '</span>';
} );
Related
- Developer overview
- Filter hooks - data-transform hooks (assets, breadcrumb, images, Customizer, copyright)
- Template structure and overrides - copy a template part into your child theme
- Assets and the manifest - the CSS/JS enqueue manifest and its filters
- Design tokens - CSS custom property reference