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:
- Child theme —
wp-content/themes/your-child-theme/anwp-sports-api-hub/ - Parent theme —
wp-content/themes/your-parent-theme/anwp-sports-api-hub/ - Plugin —
wp-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:
| File | Purpose |
|---|---|
content-game.php | Game single page (fallback when no Layout Builder layout exists) |
content-team.php | Team single page |
content-player.php | Player single page |
game/game-header.php | Game header block (scoreboard) |
game/game-card.php | Game card in lists and grids |
game/game-peek.php | Hover card popup |
game/game--team-stats.php | Team statistics comparison |
game/game--box-scores.php | Player box score tables |
game/game--timeline.php | Play-by-play timeline |
team/team--header.php | Team page header |
team/team--roster.php | Team roster grid |
team/team--standings.php | Standings table |
player/player--header.php | Player page header |
player/player--game-log.php | Player game log table |
player/player--career.php | Career 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:
- Self-documentation — you can see exactly what data is available in each template.
- Safe defaults — prevents undefined index notices if data is missing.
- 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:
- Layout Builder layout for the specific entity + sport + game state
- 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
- Layout Builder — visual block-based page composition
- Game Pages — game page structure and blocks
- Team Pages — team page structure and blocks
- Player Pages — player page structure and blocks
- CSS Customization — styling without template changes