Templates


Sports API Hub uses a template system that lets theme developers override any frontend template. Templates control the HTML structure of game pages, team pages, player pages, and all other entity displays. Copy a template file into your child theme to customize the markup — your changes survive plugin updates.

Template Resolution Chain

When the plugin renders a template, it searches for the file in this order:

  1. Child themewp-content/themes/your-child-theme/anwp-sports-api-hub/
  2. Parent themewp-content/themes/your-parent-theme/anwp-sports-api-hub/
  3. Pluginwp-content/plugins/anwp-sports-api-hub/public/templates/

The first match wins. If no override exists in your theme, the plugin’s built-in template is used.

Sport-Aware Template Priority

Templates support sport-specific and layout-specific variants. The resolution checks more specific names first:

content-game--basketball--v2.php    (sport + layout variant)
content-game--basketball.php        (sport-specific)
content-game--v2.php                (layout variant)
content-game.php                    (base template)

This means you can create a basketball-specific game template that differs from the default, without affecting other sports.

🛠️ Creating a Template Override

Step 1: Locate the Original Template

Plugin templates are in:

wp-content/plugins/anwp-sports-api-hub/public/templates/

Common template files:

FilePurpose
content-game.phpGame single page (fallback when no Layout Builder layout exists)
content-team.phpTeam single page
content-player.phpPlayer single page
game/game-header.phpGame header block (scoreboard)
game/game-card.phpGame card in lists and grids
game/game-peek.phpHover card popup
game/game--team-stats.phpTeam statistics comparison
game/game--box-scores.phpPlayer box score tables
game/game--timeline.phpPlay-by-play timeline
team/team--header.phpTeam page header
team/team--roster.phpTeam roster grid
team/team--standings.phpStandings table
player/player--header.phpPlayer page header
player/player--game-log.phpPlayer game log table
player/player--career.phpCareer statistics table

Step 2: Copy to Your Theme

Create the anwp-sports-api-hub folder in your child theme and copy the template file, preserving the directory structure:

wp-content/themes/your-child-theme/
    anwp-sports-api-hub/
        game/
            game-header.php      ← your override
        team/
            team--roster.php     ← your override

Step 3: Modify the Copy

Edit the copied file in your theme. The plugin will automatically use your version instead of its own.

Important

Always override templates in a child theme, not a parent theme. Parent theme updates would overwrite your changes.

Template Data Contract

Every plugin template starts with a wp_parse_args() call that defines all expected data keys with defaults:

$data = wp_parse_args( $data, [
    'team1_name'    => '',
    'team1_logo'    => '',
    'team1_link'    => '',
    'team2_name'    => '',
    'team2_logo'    => '',
    'status'        => '',
    'score_home'    => '',
    'score_away'    => '',
    // ... more keys
] );

This serves three purposes:

  1. Self-documentation — you can see exactly what data is available in each template.
  2. Safe defaults — prevents undefined index notices if data is missing.
  3. Stability — the data contract is maintained across plugin updates.

When customizing a template, refer to the wp_parse_args() block at the top to see all available variables.

Using load_partial()

Templates can include sub-templates (partials) using the load_partial() method:

anwp_hub()->load_partial( $data, 'general/team-section-header' );

Important

load_partial() renders output directly (echoes HTML) and returns the file path string. Do not echo its return value — just call it directly.

// ✅ Correct:
anwp_hub()->load_partial( $data, 'general/team-section-header' );

// ❌ Wrong — would output the file path as text:
echo anwp_hub()->load_partial( $data, 'general/team-section-header' );

⚙️ Available Filters

The template system provides filters for advanced customization without overriding entire files.

anwphub/template/loading_check

Control whether a template should load at all. Return false to prevent rendering.

add_filter( 'anwphub/template/loading_check', function( $should_load, $post ) {
    // Skip rendering for a specific post
    if ( $post && 123 === $post->ID ) {
        return false;
    }
    return $should_load;
}, 10, 2 );

anwphub/template/content_data

Modify the data array before it reaches the template. Useful for injecting custom values without overriding the template file.

add_filter( 'anwphub/template/content_data', function( $data, $post, $entity ) {
    if ( 'game' === $entity ) {
        $data['custom_field'] = 'my value';
    }
    return $data;
}, 10, 3 );

anwphub/template/load_default_template

Override which template file is loaded. Used internally by the Layout Builder, but available for custom logic.

add_filter( 'anwphub/template/load_default_template', function( $template, $post ) {
    if ( $post && 'anwphub_game' === $post->post_type ) {
        return get_stylesheet_directory() . '/custom-game-layout.php';
    }
    return $template;
}, 10, 2 );

Layout Builder vs. Template Overrides

The Layout Builder lets you compose pages from pre-built blocks without writing code. It takes priority over template files when a matching layout exists.

The resolution order is:

  1. Layout Builder layout for the specific entity + sport + game state
  2. Template file (child theme → parent theme → plugin)

If you have a Layout Builder layout for basketball games, template overrides for content-game--basketball.php will not be used. Remove or reset the layout to fall back to template files.

Tip

For most users, the Layout Builder is the recommended approach. Template overrides are best for developers who need full control over HTML structure.

💡 Tips

  • Start small. Override one template at a time and test thoroughly before moving to the next.
  • Check after updates. When the plugin updates, compare your overrides with the new plugin templates to incorporate any structural changes or new data keys.
  • Use filters first. If you only need to change data values or hide a block, filters are simpler and more update-safe than full template overrides.
  • Keep the data contract. Always preserve the wp_parse_args() block at the top of your overridden template. Add new keys if needed, but do not remove existing ones.

📚 Related