Loading...
Bootscore 6.1.0 is here! Learn more

Documentation Theme

Filter & Action Hooks

Enhance your theme’s versatility by effortlessly adjusting template layouts with customizable filters and actions.

Filters

Filters provide a flexible way to modify project elements in the child-theme’s functions.php file without requiring a copy of a template file. This ensures an update-proof approach to customization while allowing for creative adjustments.

How it works

Many classes and other elements are wrapped in filters, enabling modifications without storing template copies in a child theme. A basic filter consists of:

  • A filter name, e.g., bootscore/example/filter/name
  • A returnable value, such as a string containing one or more CSS classes
<div class="<?= apply_filters('bootscore/example/filter/name', 'one or more classes'); ?>">
...
</div>

Result in frontend:

<div class="one or more classes">
...
</div>

To modify these classes via a child theme, a custom function is required. This function must:

  • Have a unique function name my_fancy_filter_function
  • Return the modified value (in this case, CSS classes)
  • Be hooked into the appropriate filter bootscore/example/filter/name
/**
 * Change one or more classes into my-custom-class
 */
function my_fancy_filter_function() {
  return "my-custom-class";
}
add_filter('bootscore/example/filter/name', 'my_fancy_filter_function', 10, 2);

Result in frontend

<div class="my-custom-class">
...
</div>

Location

When a filter is used in multiple files, an additional location argument can specify where it is applied:

<?= apply_filters('bootscore/example/filter/name', 'one or more classes', 'location-in-which-template-this-filter-is-used'); ?>">

For example, the bootscore/class/container filter is present in several template files:

In header.php:

<?= apply_filters('bootscore/class/container', 'container', 'header'); ?>

In archive.php:

<?= apply_filters('bootscore/class/container', 'container', 'archive'); ?>

Applying a basic filter without specifying a location modifies all instances:

/**
 * Change entire container classes
 */
function change_entire_containers() {
  return "container-fluid";
}
add_filter('bootscore/class/container', 'change_entire_containers', 10, 2);

To modify only a specific instance, the location parameter can be checked:

/**
 * Change container class in a single file
 */
function change_container_in_single_file($string, $location) {
  if ($location == 'header') {
    return "container-fluid";
  }
  return $string;
}
add_filter('bootscore/class/container', 'change_container_in_single_file', 10, 2);

For multiple locations, conditions can be expanded:

/**
 * Change container classes in selected files
 */
function change_container_in_selected_files($string, $location) {
  if ($location == 'header' || $location == 'footer-top' || $location == 'footer-columns' || $location == 'footer-info') {
    return "container-fluid";
  }
  return $string;
}
add_filter('bootscore/class/container', 'change_container_in_selected_files', 10, 2);

Filters reference list


Actions

While filters modify existing content, actions are used to add new elements. Actions can be used for various tasks, such as inserting a message, opening a <div> in one action and closing it in another, or adding more complex functionality.

How it works

A basic action looks like this:

<?php do_action( 'bootscore_before_masthead' ); ?>

To add content at this action hook, the following are required:

  • An unique function name (e.g., my_fancy_action_function)
  • The action name (e.g., bootscore_before_masthead)
  • An echo statement to output content
/**
 * Add an alert message before the masthead.
 */
function add_alert_before_masthead() {
  echo '<div class="alert alert-danger" role="alert">This is an important message!</div>';
}
add_action('bootscore_before_masthead', 'add_alert_before_masthead');

Location

When an action is used in multiple files, an additional location argument can specify where it is applied:

<?php do_action( 'bootscore_after_primary_open', 'page-sidebar-left' ); ?>

Applying a basic action without specifying a location adds content to all instances:

/**
 * Add an alert message after primary open.
 */
function add_alert_after_primary_open() {
  echo '<div class="alert alert-danger" role="alert">This is an important message!</div>';
}
add_action('bootscore_after_primary_open', 'add_alert_after_primary_open');

To modify only a specific instance, the location parameter can be checked:

/**
 * Add an alert message after primary open for 'page-sidebar-left' location.
 */
function add_alert_after_primary_open($location) {
  if ($location == 'page-sidebar-left') {
    echo '<div class="alert alert-warning" role="alert">This is a warning alert for page-sidebar-left!</div>';
  }
}
add_action('bootscore_after_primary_open', 'add_alert_after_primary_open');

For multiple locations, the conditions can be expanded:

/**
 * Add an alert message after primary open for 'page-sidebar-left' and 'archive' location.
 */
function add_alert_after_primary_open($location) {
  if ($location == 'page-sidebar-left' || $location == 'archive') {
    echo '<div class="alert alert-warning" role="alert">This is a warning alert for page-sidebar-left and archive!</div>';
  }
}
add_action('bootscore_after_primary_open', 'add_alert_after_primary_open');

Visual guide

The following snippet will hook an alert alert-warning to all actions to create a visual map, as shown in the screenshot in header.php. If an action has a location, it will also be displayed.

/**
 * Generate hooks for all Bootscore actions
 */
$bootscore_hooks = [
  'bootscore_before_masthead',
  'bootscore_after_masthead_open',
  'bootscore_before_navbar_brand',
  'bootscore_after_nav_toggler',
  'bootscore_before_masthead_close',
  'bootscore_after_masthead',
  'bootscore_after_primary_open',
  'bootscore_before_title',
  'bootscore_after_title',
  'bootscore_before_loop',
  'bootscore_before_loop_item',
  'bootscore_before_loop_title',
  'bootscore_loop_item_after_card_body',
  'bootscore_after_loop_item',
  'bootscore_after_loop',
  'bootscore_after_featured_image',
  'bootscore_before_entry_footer',
  'bootscore_before_sidebar_widgets',
  'bootscore_after_sidebar_widgets',
  'bootscore_before_footer',
  'bootscore_footer_columns_before_container',
  'bootscore_footer_columns_after_container_open',
  'bootscore_footer_columns_before_container_close',
  'bootscore_footer_columns_after_container',
  'bootscore_footer_info_after_container_open',
];

// Add hooks dynamically
foreach ($bootscore_hooks as $hook) {
  add_action($hook, function ($location = null) use ($hook) {
    $output = '<div class="alert alert-warning"><code>' . esc_html($hook) . '</code>';
    if ($location) {
      $output .= ' (Location: <strong>' . esc_html($location) . '</strong>)';
    }
    $output .= '</div>';
    echo $output;
  });
}

Action reference list


Examples

Install a fresh child and copy each example to functions.php, see what it does in the frontend and learn by changing the classes.

Icons

/**
 * Change nav-toggler icon
 */
function change_nav_toggler_icon() {
  return '<i class="fa-solid fa-list"></i>';
}
add_filter('bootscore/icon/menu', 'change_nav_toggler_icon');

/**
 * Change search-toggler icon
 */
function change_search_toggler_icon() {
  return '<i class="fa-solid fa-glasses"></i>';
}
add_filter('bootscore/icon/search', 'change_search_toggler_icon');

/**
 * Change account-toggler user icon
 */
function change_account_toggler_icon() {
  return '<i class="fa-solid fa-person-walking-dashed-line-arrow-right"></i>';
}
add_filter('bootscore/icon/user', 'change_account_toggler_icon');

/**
 * Change cart-toggler bag icon
 */
function change_cart_toggler_icon() {
  return '<i class="fa-solid fa-cart-shopping"></i>';
}
add_filter('bootscore/icon/cart', 'change_cart_toggler_icon');

/**
 * Change back-to-cart-toggler arrow icon
 */
function change_back_to_cart_arrow_icon() {
  return '<i class="fa-solid fa-chevron-left d-none d-md-inline me-2"></i>';
}
add_filter('bootscore/icon/arrow-left', 'change_back_to_cart_arrow_icon');

/**
 * Change sidebar offcanvas-toggler icon
 */
function change_sidebar_toggler_icon() {
  return '<i class="fa-solid fa-expand"></i>';
}
add_filter('bootscore/icon/ellipsis-vertical', 'change_sidebar_toggler_icon');

/**
 * Change WooCommerce mini-cart trash icon
 */
function change_trash_icon() {
  return '<i class="fa-solid fa-xmark"></i>';
}
add_filter('bootscore/icon/trash', 'change_trash_icon');

/**
 * Change star icon
 */
function change_star_icon() {
  return '<i class="fa-solid fa-map-pin"></i>';
}
add_filter('bootscore/icon/star', 'change_star_icon');

/**
 * Change comments icon
 */
function change_comments_icon() {
  return '<i class="fa-solid fa-comment-dots"></i>';
}
add_filter('bootscore/icon/comments', 'change_comments_icon');

/**
 * Change breadcrumb home icon
 */
function change_home_icon() {
  return '<i class="fa-solid fa-igloo"></i>';
}
add_filter('bootscore/icon/home', 'change_home_icon');

Change paths to logos

/**
 * Change path to logos
 */
function change_logo_path($logo, $color) {
  if ($color === 'theme-dark') {
    return get_stylesheet_directory_uri() . '/path/to/dark-logo.png';
  }
  return get_stylesheet_directory_uri() . '/path/to/default-logo.png';
}
add_filter('bootscore/logo', 'change_logo_path', 10, 2);

Position and bg

/**
 * Header position and bg
 */
function header_bg_class() {
  return "position-relative bg-body shadow-sm";
}
add_filter('bootscore/class/header', 'header_bg_class', 10, 2);


/**
 * Header search collapse position and bg
 */
function header_collapse_bg_class() {
  return "bg-body shadow-sm position-absolute start-0 end-0";
}
add_filter('bootscore/class/header/collapse', 'header_collapse_bg_class', 10, 2);

Breakpoints

Change navbar expand to md:

/**
 * Header navbar breakpoint
 */
function header_navbar_breakpoint_class() {
  return "navbar-expand-md";
}
add_filter('bootscore/class/header/navbar/breakpoint', 'header_navbar_breakpoint_class', 10, 2);

/**
 * Header navbar toggler breakpoint
 */
function header_navbar_toggler_breakpoint_class() {
  return "d-md-none";
}
add_filter('bootscore/class/header/navbar/toggler/breakpoint', 'header_navbar_toggler_breakpoint_class', 10, 2);

Navbar always collapsed:

/**
 * Header navbar breakpoint
 */
function header_navbar_breakpoint_class() {
  return "";
}
add_filter('bootscore/class/header/navbar/breakpoint', 'header_navbar_breakpoint_class', 10, 2);

/*
 * Header navbar toggler breakpoint
 */
function header_navbar_toggler_breakpoint_class() {
  return "";
}
add_filter('bootscore/class/header/navbar/toggler/breakpoint', 'header_navbar_toggler_breakpoint_class', 10, 2);

Buttons

Change all header button classes at once:

/**
 * Change all header buttons
 */
function header_button_class() {
  return "btn btn-light";
}
add_filter('bootscore/class/header/button', 'header_button_class', 10, 2);

Change a single button class only. For example the navbar-toggler:

/**
 * Change single header button
 */
function header_button_class($string, $location) {
  if ($location == 'nav-toggler') {
    return "btn btn-light";
  }
  return $string;
}
add_filter('bootscore/class/header/button', 'header_button_class', 10, 2);

Or select multiple buttons. For example account-toggler and mini-cart-toggler:

/**
 * Change selected header buttons
 */
function header_button_class($string, $location) {
  if ($location == 'account-toggler' || $location == 'cart-toggler') {
    return "btn btn-light";
  }
  return $string;
}
add_filter('bootscore/class/header/button', 'header_button_class', 10, 2);
/**
 * Change navbar offcanvas title
 */
function change_navbar_offcanvas_title($title) {
  return 'My Menu';
}
add_filter('bootscore/offcanvas/navbar/title', 'change_navbar_offcanvas_title');

Add a mobile logo, center the logo and move menu to left

/**
 * Header hook a mobile logo
 */
function hook_before_navbar_brand() {
  ?>
    <a class="position-absolute top-50 start-50 translate-middle d-sm-none" href="<?= esc_url(home_url()); ?>">
      <img src="<?= esc_url(get_stylesheet_directory_uri()); ?>/assets/img/logo/logo-sm.svg" alt="<?php bloginfo('name'); ?> Logo" class="d-td-none">
      <img src="<?= esc_url(get_stylesheet_directory_uri()); ?>/assets/img/logo/logo-sm-theme-dark.svg" alt="<?php bloginfo('name'); ?> Logo" class="d-tl-none">
    </a>  
  <?php
}
add_action( 'bootscore_before_navbar_brand', 'hook_before_navbar_brand' );

/**
 * Header navbar-brand
 */
function header_navbar_brand_class() {
  return "position-absolute top-50 start-50 translate-middle d-none d-sm-block";
}
add_filter('bootscore/class/header/navbar-brand', 'header_navbar_brand_class', 10, 2);

/**
 * Header menu position
 */
function header_navbar_menu_class() {
  return "ms-start";
}
add_filter('bootscore/class/header/navbar-nav', 'header_navbar_menu_class', 10, 2);

/**
 * Header actions
 */
function header_actions_class() {
  return "d-flex align-items-center flex-grow-1 justify-content-lg-end";
}
add_filter('bootscore/class/header-actions', 'header_actions_class', 10, 2);

/**
 * Move nav-toggler to first
 */
function header_nav_toggler_button_spacer_class($string, $location) {
  if ($location == 'nav-toggler') {
    return "order-first me-auto";
  }
  return $string;
}
add_filter('bootscore/class/header/action/spacer', 'header_nav_toggler_button_spacer_class', 10, 2);

/**
 * Change header menu offcanvas direction
 */
function header_menu_offcanvas_directions($string, $location) {
  if ($location == 'menu') {
    return "start";
  }
  return $string;
}
add_filter('bootscore/class/header/offcanvas/direction', 'header_menu_offcanvas_directions', 10, 2);

Search collapse breakpoint (if WooCommerce is not installed)

/**
* Change search collapse breakpoint if WooCommerce is not installed
* Leave breakpoint empty to keep search always collapsed
*/
function change_search_collapse_breakpoint() {
  return 'xxl';
}
add_filter('bootscore/class/header/search/breakpoint', 'change_search_collapse_breakpoint');
/**
 * Change breadcrumb <nav> classes
 */
function change_breadcrumb_nav_class() {
  return 'overflow-x-auto text-nowrap mb-4 mt-2 py-2 px-3 border rounded';
}
add_filter('bootscore/class/breadcrumb/nav', 'change_breadcrumb_nav_class');

/**
 * Change breadcrumb <ol> classes
 */
function change_breadcrumb_ol_class() {
  return 'flex-nowrap mb-0';
}
add_filter('bootscore/class/breadcrumb/ol', 'change_breadcrumb_ol_class');

/**
 * Change breadcrumb <a> classes
 */
function change_breadcrumb_a_class() {
  return 'text-decoration-none link-danger';
}
add_filter('bootscore/class/breadcrumb/item/link', 'change_breadcrumb_a_class');

Loop

Vertical loop cards and read-more button

/**
 * Hook the function to 'bootscore_before_loop'
 */
function hook_before_loop() {
  echo '<div class="row">';
}
add_action( 'bootscore_before_loop', 'hook_before_loop' );

/**
 * Hook the function to 'bootscore_before_loop_item'
 */
function hook_before_loop_item() {
  echo '<div class="col-md-6 col-lg-4 mb-4">';
}
add_action( 'bootscore_before_loop_item', 'hook_before_loop_item' );

/**
 * Hook the function to 'bootscore_after_loop_item'
 */
function hook_after_loop_item() {
  echo '</div>';
}
add_action( 'bootscore_after_loop_item', 'hook_after_loop_item' );

/**
 * Hook the function to 'bootscore_after_loop'
 */
function hook_after_loop() {
  echo '</div>';
}
add_action( 'bootscore_after_loop', 'hook_after_loop' );

/**
 * Change loop card class
 */
function loop_card_class() {
  return "card border-0 shadow h-100";
}
add_filter('bootscore/class/loop/card', 'loop_card_class', 10, 2);

/**
 * Change loop card row class
 */
function loop_card_row_class() {
  return "d-flex flex-column h-100";
}
add_filter('bootscore/class/loop/card/row', 'loop_card_row_class', 10, 2);

/**
 * Change loop image col class
 */
function loop_image_col_class() {
  return "";
}
add_filter('bootscore/class/loop/card/image/col', 'loop_image_col_class', 10, 2);

/**
 * Change loop content col class
 */
function loop_content_col_class() {
  return "d-flex flex-column h-100";
}
add_filter('bootscore/class/loop/card/content/col', 'loop_content_col_class', 10, 2);

/**
 * Change loop image class
 */
function loop_image_class() {
  return "card-img-top";
}
add_filter('bootscore/class/loop/card/image', 'loop_image_class', 10, 2);

/**
 * Change loop card-body class
 */
function loop_card_body_class() {
  return "card-body h-100 d-flex flex-column";
}
add_filter('bootscore/class/loop/card/body', 'loop_card_body_class', 10, 2);

/**
 * Change loop excerpt card-text class
 */
function loop_card_text_excerpt_class() {
  return "card-text small";
}
add_filter('bootscore/class/loop/card-text/excerpt', 'loop_card_text_excerpt_class', 10, 2);

/**
 * Change loop read-more card-text class
 */
function loop_card_text_read_more_class() {
  return "card-text mt-auto";
}
add_filter('bootscore/class/loop/card-text/read-more', 'loop_card_text_read_more_class', 10, 2);

/**
 * Change loop read-more class
 */
function loop_read_more_class() {
  return "btn btn-primary d-block";
}
add_filter('bootscore/class/loop/read-more', 'loop_read_more_class', 10, 2);

/**
 * Change loop read-more text
 */
function change_loop_read_more_text($title) {
  return 'Continue reading <i class="fa-solid fa-arrow-right"></i>';
}
add_filter('bootscore/loop/read-more/text', 'change_loop_read_more_text');


// Sticky

/**
 * Hook the function to 'bootscore_before_loop_sticky'
 */
function hook_before_loop_sticky() {
  echo '<div class="row">';
}
add_action( 'bootscore_before_loop_sticky', 'hook_before_loop_sticky' );

/**
 * Hook the function to 'bootscore_before_loop_item'
 */
function hook_before_loop_item_sticky() {
  echo '<div class="col-md-6 mb-4">';
}
add_action( 'bootscore_before_loop_item_sticky', 'hook_before_loop_item_sticky' );

/**
 * Hook the function to 'bootscore_after_loop_item_sticky'
 */
function hook_after_loop_item_sticky() {
  echo '</div>';
}
add_action( 'bootscore_after_loop_item_sticky', 'hook_after_loop_item_sticky' );

/**
 * Hook the function to 'bootscore_after_loop'
 */
function hook_after_loop_sticky() {
  echo '</div>';
}
add_action( 'bootscore_after_loop_sticky', 'hook_after_loop_sticky' );

Contents

Spacer

Change entire spacers:

/**
 * Change all content spacers
 */
function change_content_spacer($spacer) {
  return 'my-5 p-5';
}
add_filter('bootscore/class/content/spacer', 'change_content_spacer');

Change spacer on an single file:

/**
 * Change content spacer on an archive page of the post type "product"
 */
function change_content_spacer($spacer) {
  if (is_post_type_archive('product')) {
    return 'my-5 p-5';
  }
  return $spacer;
}
add_filter('bootscore/class/content/spacer', 'change_content_spacer');

Hide meta post updated time

/**
 * Hide meta post updated time
 */
function disable_updated_time_display($show_updated_time) {
  return false;
}
add_filter('bootscore/meta/time/updated', 'disable_updated_time_display');

Hide meta post author

/**
 * Hide meta post author
 */
function hide_author_function($display_author) {
  return false;
}
add_filter('bootscore/meta/author', 'hide_author_function');

Main col, sidebar and breakpoints

/**
 * Change main content col
 */
function change_content_col_size($col_size) {
  if (is_active_sidebar('sidebar-1')) {
    return "col-md-9 col-lg-8 col-xl-9";
  }
  return $col_size;
}
add_filter('bootscore/class/main/col', 'change_content_col_size', 11);

/**
 * Change sidebar col
 */
function change_sidebar_col_size($col_size) {
  return "col-md-3 col-lg-4 col-xl-3 order-first order-md-2";
}
add_filter('bootscore/class/sidebar/col', 'change_sidebar_col_size');

/**
 * Change sidebar responsive offcanvas
 */
function change_sidebar_offcanvas($col_size) {
  return "offcanvas-md offcanvas-start";
}
add_filter('bootscore/class/sidebar/offcanvas', 'change_sidebar_offcanvas');

/**
 * Change sidebar toggler button breakpoint and class
 */
function change_sidebar_toggler($col_size) {
  return "d-md-none btn btn-light w-100 mb-4 d-flex justify-content-between align-items-center";
}
add_filter('bootscore/class/sidebar/button', 'change_sidebar_toggler');

Category badge

/**
 * Change category badge class
 */
function change_category_badge_link_class($class) {
  return 'badge bg-warning-subtle border border-warning-subtle text-warning-emphasis rounded-pill text-decoration-none';
}
add_filter('bootscore/class/badge/category', 'change_category_badge_link_class');

Tag badge

/**
 * Change tags badge class
 */
function change_tag_link_class($class) {
  return 'badge bg-danger-subtle border border-danger-subtle text-danger-emphasis rounded-pill text-decoration-none';
}
add_filter('bootscore/class/badge/tag', 'change_tag_link_class');

Blocks

Widget search button

/**
 * Change searchform block widget button class
 */
function change_block_widget_search_button_class($class) {
  return 'btn btn-outline-danger';
}
add_filter('bootscore/class/widget/search/button', 'change_block_widget_search_button_class');

Widget categories badge

/**
 * Change widget categories badge
 */
function change_block_widget_categories_badge($block_content, $block) {
  
    $search  = array(
      '<span class="badge bg-primary-subtle text-primary-emphasis">'
    );
    $replace = array(
      '<span class="badge bg-danger rounded-pill">'
    );  

  return str_replace($search, $replace, $block_content);
}
add_filter('bootscore/block/categories/content', 'change_block_widget_categories_badge', 10, 2);

Table

/**
 * Change table block classes
 */
function block_table_class() {
  return "table-bordered table-striped table-hover";
}
add_filter('bootscore/class/block/table', 'block_table_class', 10, 2);
/**
 * Footer top classes
 */
function footer_top_class() {
  return "bg-success text-white border-top border-secondary pt-5 pb-4";
}
add_filter('bootscore/class/footer/top', 'footer_top_class', 10, 2);
/**
 * Change footer column wrapper classes
 */
function footer_class() {
  return "bg-dark text-white border-top border-secondary pt-5 pb-3";
}
add_filter('bootscore/class/footer/columns', 'footer_class', 10, 2);

Change all footer columns:

/**
 * Change footer 1-4 col
 */
function footer_col_class() {
  return "col-12 col-md-6 col-lg-3";
}
add_filter('bootscore/class/footer/col', 'footer_col_class', 10, 2);

Change each footer-column:

/**
 * Change footer 1 col
 */
function footer_col_1_class($string, $location) {
  if ($location == 'footer-1') {
    return "col-6 col-md-12 col-lg-6";
  }
  return $string;
}
add_filter('bootscore/class/footer/col', 'footer_col_1_class', 10, 2);

/**
 * Change footer 2, 3, 4 col
 */
function footer_col_2_3_4_class($string, $location) {
  if ($location == 'footer-2' || $location == 'footer-3' || $location == 'footer-4') {
    return "col-6 col-md-4 col-lg-2";
  }
  return $string;
}
add_filter('bootscore/class/footer/col', 'footer_col_2_3_4_class', 10, 2);
/**
 * Change footer info classes
 */
function footer_info_class() {
  return "bg-dark text-white border-top border-secondary py-2 small";
}
add_filter('bootscore/class/footer/info', 'footer_info_class', 10, 2);

To-top button

/**
 * Change to-top button classes
 */
function footer_to_top_button_class() {
  return "btn btn-light shadow-lg";
}
add_filter('bootscore/class/footer/to_top_button', 'footer_to_top_button_class', 10, 2);

WooCommerce

Grid columns

/**
 * Change WooCommerce column class
 */
function change_woo_columns($class) {
  return 'col-6 col-lg-4';
}
add_filter('bootscore/class/woocommerce/col', 'change_woo_columns');
/**
 * Move WooCommerce content to right (Sidebar left)
 */
function move_wc_content_col_to_end($col_size) {
  if (is_woocommerce() && is_active_sidebar('sidebar-1')) {
    return "col-lg-9 order-lg-last";
  }
  return $col_size;
}
add_filter('bootscore/class/main/col', 'move_wc_content_col_to_end', 11);

Disable scripts

Font Awesome

/**
 * Disable Font Awesome
 */
add_filter('bootscore/load_fontawesome', '__return_false');

AJAX cart

/**
 * Disable AJAX cart
 */
add_filter('bootscore/load_ajax_cart', '__return_false');

scssphp compiler

/**
 * Disable scssphp compiler
 */ 
add_filter('bootscore/scss/disable_compiler', '__return_true');
To top