
🐛 WordPress and JoomSport: fixing bugs and customizing the plugin
Sports websites on WordPress are a rare breed. When a tennis federation needed a site with match schedules, tournament tables, and player profiles, the plugin options turned out to be frustratingly limited. JoomSport PRO became the only viable choice, but even it required considerable effort.
The plugin has a steep learning curve: configuring it for a specific sport takes time, and in places the code behaves as though it wasn't written for experienced WordPress users. On the other hand, JoomSport has a strong support team that responds to every helpdesk inquiry, and that's a serious plus when you're customizing the plugin for a project.
Below is a collection of tested fixes and snippets gathered from a real project. They solve specific problems: from annoying copyright notices to content filtering and output templates. All code fragments are current for JoomSport version 5.7.x (as of June 2026, 5.7.8).
💡 Quick overview:
- Removing the plugin copyright: one line in the template
- Fixing pagination and the division by zero error
- Adding thumbnail support for JoomSport posts
- Writing a function to auto-add featured images to the gallery
- Calculating and saving player age in a meta field
- Saving the first letter of the last name for sorting
- Creating output templates for custom post types
Removing the JoomSport copyright
In the free version, the plugin displays a "powered by JoomSport" link in the footer of season pages. A small thing, but it looks out of place on a client site.
File to edit:
1 /wp-content/plugins/joomsport-sports-league-results-management/sportleague/views/default/season.php
Around line 79, find and remove the line containing the link to joomsport.com. After a plugin update, you'll need to repeat this fix, so keep that in mind when setting up auto-updates.
Fixing the pagination error
If this warning appears in your logs:
Warning: Division by zero in.../class-jsport-pagination.php on line 72
, the plugin is attempting to divide by zero when calculating pages. The problem occurs when the $limit variable is undefined or equals zero.
File:
1 /wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/class-jsport-pagination.php
Find line 70:
1 $npage = ceil($this->setcurrent / $limit);
Replace with:
1 if (isset($limit) && $limit > 0) { 2 $npage = ceil($this->setcurrent / $limit); 3 }
Wrapping the division in a check: if $limit is not set or equals zero, the calculation simply doesn't execute, and the error disappears.
Adding thumbnail support for JoomSport posts
By default, JoomSport custom post types (joomsport_player, joomsport_season, and others) don't support thumbnails. Without this, you can't build a proper gallery or player card.
Add to your theme's functions.php:
1 add_post_type_support('joomsport_player', 'thumbnail'); 2 add_post_type_support('joomsport_season', 'thumbnail');
Now the standard "Featured image" block will appear in the admin panel for players and seasons. Similarly, you can add thumbnail support for any JoomSport custom type by substituting the appropriate slug.
Framework for JoomSport data processing functions
All the following snippets work inside a single save_post hook. It fires when a post is saved and allows you to automatically populate meta fields.
Create this wrapper in functions.php:
1 function my_custom_save_post($post_id) { 2 3 function jswpla__meta_save_SDStudio($post_id) { 4 5 // Place functions from the sections below here 6 7 } 8 add_action('save_post', 'jswpla__meta_save_SDStudio'); 9 } 10 add_action('save_post_joomsport_player', 'my_custom_save_post');
The save_post_joomsport_player hook ensures execution only when saving "player" type posts. For other types (joomsport_season, joomsport_match), change the suffix.
Auto-adding featured image to gallery
When you have dozens of players, manually adding images to the JoomSport gallery becomes tedious. Here's a function that automatically grabs the featured image ID when saving a post and adds it first to the gallery:
1 $thumbnail_ID = get_post_thumbnail_id($post_id); 2 $values = [$thumbnail_ID]; 3 4 $check_id_thumb = get_post_meta($post_id, 'vdw_gallery_id'); 5 $My_False = false; 6 7 foreach ($check_id_thumb as $metakey) { 8 if (strpos($values, $check_id_thumb) !== false) { 9 $My_False = true; 10 } 11 } 12 13 if (!$My_False) { 14 add_post_meta($post_id, 'vdw_gallery_id', $values); 15 }
The logic is simple: get the featured image ID, check if it already exists in the vdw_gallery_id meta field. If not, add it. If it does, skip it to avoid creating duplicates.
Calculating player age in a meta field
JoomSport stores the player's birth date in the _joomsport_player_ef meta field. To display age on the site, you need to calculate and save it first. The code is based on a solution from StackExchange and ACF documentation.
1 $date_of_birth = get_post_meta($post_id, '_joomsport_player_ef', false); 2 3 foreach ($date_of_birth as $metakey) { 4 $metakey_borthay = $metakey[3]; 5 } 6 7 $age = intval(date('Y', time() - strtotime($metakey_borthay))) - 1970; 8 9 delete_post_meta($post_id, 'age_field'); 10 add_post_meta($post_id, 'age_field', $age);
The birth date is stored in the fourth element of the array (index [3]) of the _joomsport_player_ef meta field. The function extracts it, calculates the age, and writes it to a separate age_field meta field, which can then be used in templates or for filtering.
Saving the first letter of the last name
For sorting players alphabetically or quick searching, it's convenient to have a separate field with the first letter of the last name. JoomSport stores first and last names in the _joomsport_player_personal meta field.
1 $val_last_name = get_post_meta($post_id, '_joomsport_player_personal', false); 2 3 foreach ($val_last_name as $metakey) { 4 $metakey_Last_Name = $metakey['last_name']; 5 } 6 7 $metakey_Last_Name = preg_split('//u', $metakey_Last_Name, -1, PREG_SPLIT_NO_EMPTY); 8 $metakey_Last_Name = $metakey_Last_Name[0]; 9 10 $check_Liter_Last_Name = get_post_meta($post_id, 'First_letter_Last_Name'); 11 $My_False_Liter_Last_Name = false; 12 13 foreach ($metakey_Last_Name as $check_liter) { 14 if (strpos($check_Liter_Last_Name, $metakey_Last_Name) !== false) { 15 $My_False_Liter_Last_Name = true; 16 } 17 } 18 19 if (!$My_False_Liter_Last_Name) { 20 update_post_meta($post_id, 'First_letter_Last_Name', $metakey_Last_Name); 21 }
preg_split with the PREG_SPLIT_NO_EMPTY flag correctly splits a UTF-8 string into characters, including Cyrillic. The first character of the last name array is saved to the First_letter_Last_Name meta field.
Search and replace text across the entire site
A universal snippet for bulk text replacement in content and excerpts. Useful not only for JoomSport; use it for any global edits.
1 function replace_text_wps($text) { 2 $replace = array( 3 'getimagesizefromstring' => 'excerpt', 4 'functidrgon' => 'function' 5 ); 6 $text = str_replace(array_keys($replace), $replace, $text); 7 return $text; 8 } 9 add_filter('the_content', 'replace_text_wps'); 10 add_filter('the_excerpt', 'replace_text_wps');
Add your own pairs to the $replace array, and the replacement will apply to all posts on the fly. Works faster than search-replace plugins, but remember: this is a filter, the original content in the database remains unchanged.
Output templates for JoomSport custom types
JoomSport registers several custom post types, including joomsport_player, joomsport_season, and joomsport_match. By default, they're rendered through the theme's single.php, and this almost always looks sloppy.
The solution is to create a separate template. For the "player" type:
1 single-joomsport_player.php
The file goes in the theme root. The naming follows the WordPress template hierarchy rule: single-{slug}.php. Similarly: single-joomsport_season.php for seasons, single-joomsport_match.php for matches.
Take the file contents from your theme's single.php and adapt them to the structure you need. For example, for the Cactus theme, a basic player page template looks like this:
1 <?php 2 /* Template Name: Post joomsport_player */ 3 4 get_header(); 5 6 $page_sidebar_layout = apply_filters('cactus_page_sidebar_layout', cactus_option('page_sidebar_layout')); 7 switch ($page_sidebar_layout) { 8 case 'left': 9 $aside_class = 'left-aside'; 10 break; 11 case 'right': 12 $aside_class = 'right-aside'; 13 break; 14 default: 15 $aside_class = 'no-aside'; 16 break; 17 } 18 ?> 19 20 <?php echo apply_filters('cactus_page_title_bar', '', 'page'); ?> 21 22 <div class="page-wrap"> 23 <?php do_action('cactus_before_page_wrap'); ?> 24 <div class="container"> 25 <div class="page-inner row <?php echo $aside_class; ?>"> 26 <div class="col-main"> 27 <section class="post-main" role="main" id="content"> 28 <article class="post-entry text-left"> 29 <?php do_action('cactus_before_page_content'); ?> 30 31 <?php 32 while (have_posts()) : 33 the_post(); 34 get_template_part('template-parts/page/content'); 35 the_posts_pagination(array( 36 'prev_text' => '<i class="fa fa-arrow-left"></i><span class="screen-reader-text">' . __('Previous page', 'cactus') . '</span>', 37 'next_text' => '<span class="screen-reader-text">' . __('Next page', 'cactus') . '</span><i class="fa fa-arrow-right"></i>', 38 'before_page_number' => '<span class="meta-nav screen-reader-text">' . __('Page', 'cactus') . ' </span>', 39 )); 40 endwhile; 41 ?> 42 43 <?php do_action('cactus_after_page_content'); ?> 44 </article> 45 46 <?php do_action('cactus_after_post_entry'); ?> 47 </section> 48 </div> 49 </div> 50 </div> 51 <?php do_action('cactus_after_page_wrap'); ?> 52 </div> 53 54 <?php get_footer(); ?> 55
Copy this code and replace the CSS classes and hooks with those your theme uses. The key is the structure: header, container, sidebar (optional), main loop, and footer.
For a quick start with the plugin, watch the official tutorial from BearDev: 11 minutes that will save you a couple hours of setup.
⁉️🤔 Frequently asked questions
Do these fixes work on the PRO version of JoomSport?
Yes, all snippets are universal and have been tested on the PRO version as well. The
save_post_joomsport_*hooks and meta fields are identical in the free and paid versions. The only nuance: the PRO version adds its own custom post types, so check the slug before adding thumbnail support.
What should I do if the plugin stops working after an edit?
Roll back the changes: all edits are made in the theme's
functions.phpor in separate template files; the plugin core is not affected. The exceptions are removing the copyright and fixing pagination: those involve editing the plugin's own files, and they'll be overwritten on update. Before making any edits, back up the file you're changing.
Can I use these functions for post types from other plugins?
Yes, the approach is universal. Replace
joomsport_playerwith the slug of the custom type you need, and_joomsport_player_efwith its meta field. The framework code (the wrapper with thesave_posthook) and the check logic (get_post_meta→foreach→ condition) can be reused exactly as written.
How do I add thumbnail support for all JoomSport types at once?
Loop through an array of slugs:
1 $joomsport_types = ['joomsport_player', 'joomsport_season', 'joomsport_match', 'joomsport_team']; 2 foreach ($joomsport_types as $type) { 3 add_post_type_support($type, 'thumbnail'); 4 }
For a list of all the plugin's custom types, check its settings or use
var_dump(get_post_types()).
Why shouldn't I use JoomSport's extra fields for filtering?
JoomSport dumps all extra field values into a single array. Accessing a specific field from the frontend (for example, during AJAX filtering) is practically impossible because the data is concatenated. If you need to filter players by age, first letter, or any other criterion, save the value to a separate meta field, as shown in the sections on
age_fieldandFirst_letter_Last_Name.
Should you use JoomSport for your project?
JoomSport is a niche but powerful tool. If you need a sports league site with tables, schedules, and profiles, alternatives on WordPress are frankly scarce. The plugin is actively developed: as of June 2026, the current version is 5.7.8, and the developers promptly patch vulnerabilities and add features.
The weak point is the learning curve. Initial setup requires patience, and some plugin behavior is designed more for developers than for regular users. But beardev's support is genuinely good: every helpdesk message gets a detailed response, often with a ready-made snippet.
If your project is sports-related and your budget is limited, go with JoomSport and budget time for customization. The code in this article will address most of the typical problems developers encounter when integrating the plugin into a live site.



