{"id":305260,"date":"2026-05-25T20:16:57","date_gmt":"2026-05-25T20:16:57","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/afvd-data\/"},"modified":"2026-05-25T21:31:03","modified_gmt":"2026-05-25T21:31:03","slug":"gridirontables-afvd","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/gridirontables-afvd\/","author":23488683,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"3.1.3","stable_tag":"3.1.3","tested":"6.9.4","requires":"5.9","requires_php":"7.4","requires_plugins":null,"header_name":"Gridirontables AFVD \u2013 League tables & schedules - data provided by AFVD","header_author":"Daniel Schmidt-Richert","header_description":"Display American football league standings and schedules from publicly available XML data on your WordPress site.","assets_banners_color":"ffffff","last_updated":"2026-05-25 21:31:03","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/slayer01.github.io\/gridirontables-afvd\/","header_author_uri":"https:\/\/foo.boo","rating":0,"author_block_rating":0,"active_installs":0,"downloads":37,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"3.0.2":{"tag":"3.0.2","author":"dsfooboo","date":"2026-05-25 20:15:15"},"3.1.3":{"tag":"3.1.3","author":"dsfooboo","date":"2026-05-25 21:31:03"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3548218,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3548218,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3548218,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3548218,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["3.0.2","3.1.3"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3548218,"resolution":"1","location":"assets","locale":"","width":1395,"height":367},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3548218,"resolution":"2","location":"assets","locale":"","width":1395,"height":806},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3548218,"resolution":"3","location":"assets","locale":"","width":1107,"height":416},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3548218,"resolution":"4","location":"assets","locale":"","width":1107,"height":1008}},"screenshots":{"1":"Frontend standings table with the configured team highlighted","2":"Frontend game schedule for a configured league","3":"Admin: configure the leagues to import on the Leagues tab","4":"Admin: run imports, view raw data, and look up shortcodes on the Import tab"}},"plugin_section":[],"plugin_tags":[264395,9084,4062,4776,30579],"plugin_category":[37,40],"plugin_contributors":[264396],"plugin_business_model":[],"class_list":["post-305260","plugin","type-plugin","status-publish","hentry","plugin_tags-american-football","plugin_tags-germany","plugin_tags-schedule","plugin_tags-sports","plugin_tags-standings","plugin_category-arts-and-entertainment","plugin_category-calendar-and-events","plugin_contributors-dsfooboo","plugin_committers-dsfooboo"],"banners":{"banner":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/banner-772x250.png?rev=3548218","banner_2x":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/banner-1544x500.png?rev=3548218","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/icon-128x128.png?rev=3548218","icon_2x":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/icon-256x256.png?rev=3548218","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/screenshot-1.png?rev=3548218","caption":"Frontend standings table with the configured team highlighted"},{"src":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/screenshot-2.png?rev=3548218","caption":"Frontend game schedule for a configured league"},{"src":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/screenshot-3.png?rev=3548218","caption":"Admin: configure the leagues to import on the Leagues tab"},{"src":"https:\/\/ps.w.org\/gridirontables-afvd\/assets\/screenshot-4.png?rev=3548218","caption":"Admin: run imports, view raw data, and look up shortcodes on the Import tab"}],"raw_content":"<!--section=description-->\n<p>Gridirontables AFVD fetches league standings and game schedules from a publicly available XML API, stores them locally, and displays them via shortcodes.<\/p>\n\n<p>This plugin is an independent project and is not affiliated with, endorsed by, or in any way officially connected to the AFVD (American Football Verband Deutschland) or any of its member associations.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li>Import standings and schedules for any league available in the XML API<\/li>\n<li>Automatic sync via WP-Cron (hourly, twice daily, daily, or manual)<\/li>\n<li>Per-league team name for highlighting<\/li>\n<li>Configurable table colors (header, highlight) with active theme palette support<\/li>\n<li>Groups are auto-detected from imported data<\/li>\n<li>Responsive schedule table for mobile<\/li>\n<li>Raw data viewer in the admin panel<\/li>\n<li>German date format for schedules<\/li>\n<\/ul>\n\n<h4>Shortcodes<\/h4>\n\n<ul>\n<li><code>[gridirontables_afvd_standings league=\"slug\"]<\/code> \u2014 League standings table<\/li>\n<li><code>[gridirontables_afvd_schedule league=\"slug\"]<\/code> \u2014 Game schedule table<\/li>\n<\/ul>\n\n<h4>Schedule Attributes<\/h4>\n\n<ul>\n<li><code>home_only=\"1\"<\/code> \u2014 Show only home games of the configured team<\/li>\n<li><code>show=\"upcoming\"<\/code> \u2014 Show only upcoming games<\/li>\n<li><code>show=\"past\"<\/code> \u2014 Show only past games<\/li>\n<li><code>limit=\"5\"<\/code> \u2014 Limit number of games shown<\/li>\n<\/ul>\n\n<h4>Shared Attributes<\/h4>\n\n<ul>\n<li><code>group=\"A\"<\/code> \u2014 Show only a specific group<\/li>\n<li><code>highlight=\"Team Name\"<\/code> \u2014 Override team name for highlighting<\/li>\n<li><code>class=\"my-class\"<\/code> \u2014 Add custom CSS class<\/li>\n<li><code>saison=\"2026\"<\/code> \u2014 Override the season label shown in the heading<\/li>\n<\/ul>\n\n<h4>Standings Attributes<\/h4>\n\n<ul>\n<li><code>format=\"wins\"<\/code> (default) \u2014 BSO record layout: W-L (Quotient) \/ TD \/ Home-Away<\/li>\n<li><code>format=\"points\"<\/code> \u2014 Legacy points layout: P+ \/ P- \/ TD+ \/ TD- (for archive data)<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin through the Plugins menu<\/li>\n<li>Go to <strong>Gridirontables AFVD<\/strong> in the admin menu to configure leagues<\/li>\n<li>Import data and use shortcodes on your pages<\/li>\n<\/ol>\n\n<!--section=changelog-->\n<h4>3.1.3<\/h4>\n\n<ul>\n<li>Fix: post-import row counts in the Import tab reported the wrong saison's count. <code>import_league()<\/code> called <code>get_counts($liga_code)<\/code> without passing the saison, so importing an archive entry would store the right rows in the DB but display the count from the current saison \u2014 making two leagues with the same liga_code look identical even though the underlying data was different. Now the count is scoped to the saison that was just imported.<\/li>\n<li>Migration robustness: replaced <code>SHOW INDEX \u2026 WHERE<\/code> with a fetch-all-then-filter-in-PHP approach so the saison-in-unique-key migration runs reliably on all MySQL\/MariaDB versions; table and key names are now backtick-quoted.<\/li>\n<\/ul>\n\n<h4>3.1.2<\/h4>\n\n<ul>\n<li>Leagues form: when duplicate slugs or duplicate (liga_code, saison) pairs are submitted, <strong>nothing is saved<\/strong> and the form re-renders with the user's unsaved input intact plus a red error notice listing the row numbers and what to fix. Previously the duplicate row was silently skipped, which lost the user's typing.<\/li>\n<\/ul>\n\n<h4>3.1.1<\/h4>\n\n<ul>\n<li>Two league entries can now coexist with the same Liga Code but different Saison values \u2014 useful for displaying current + archive data side by side. The <code>saison<\/code> column is part of the unique key on both DB tables; DB schema bumped to 1.5 (the key is migrated automatically on upgrade)<\/li>\n<li>Validation on the Leagues form: duplicate slugs or duplicate (liga_code, saison) pairs are now skipped on save and surfaced in an admin notice \u2014 previously the second entry silently overwrote the first<\/li>\n<li>Import buttons, count cells, and raw-data viewer in the admin Import tab key off the league slug instead of the liga_code so multi-saison setups address the right league entry<\/li>\n<li>Import tab now shows the per-league Saison column and counts are scoped to that saison<\/li>\n<\/ul>\n\n<h4>3.1.0<\/h4>\n\n<ul>\n<li>New BSO-style standings layout (default): <code>Rank | Team | Record (W-L (Quotient)) | TD (TD+:TD-) | Home\/Away<\/code>, matching the official footballverband.de output<\/li>\n<li>Legacy <code>P+ \/ P- \/ TD+ \/ TD-<\/code> layout remains available via <code>format=\"points\"<\/code> on the shortcode or per league config (for archive seasons that still use the old points system)<\/li>\n<li>New per-league <strong>Saison<\/strong> field \u2014 when set, gets appended to the table heading and passed to the XML API as the <code>Saison<\/code> parameter so archive seasons can be imported<\/li>\n<li>Shortcode attributes <code>format<\/code> and <code>saison<\/code> for ad-hoc overrides<\/li>\n<li>Importer now captures <code>Gameswin<\/code>, <code>Gamesloose<\/code>, <code>Gamestied<\/code>, <code>Quotient<\/code>, Home\/Away splits and overtime scores (<code>OTHeim<\/code> \/ <code>OTGast<\/code>) \u2014 DB schema bumped to 1.4<\/li>\n<li><strong>Important after upgrade:<\/strong> run a fresh import (Gridirontables AFVD \u2192 Import) to populate the new columns; until you do, standings fall back to the legacy <code>points<\/code> layout<\/li>\n<\/ul>\n\n<h4>3.0.2<\/h4>\n\n<ul>\n<li>Corrected the <code>Contributors<\/code> field in <code>readme.txt<\/code> to the WordPress.org account that owns the plugin (<code>dsfooboo<\/code>)<\/li>\n<li>Removed the deprecated <code>[dsfooboo_football_data_*]<\/code>, <code>[footballdata_*]<\/code> and <code>[afvdata_*]<\/code> shortcode aliases to satisfy the WordPress.org Plugin Check prefix requirement \u2014 only <code>[gridirontables_afvd_*]<\/code> is registered now (existing pages using the old tags must be updated)<\/li>\n<\/ul>\n\n<h4>3.0.1<\/h4>\n\n<ul>\n<li>Trim short description to fit the 150-character readme limit<\/li>\n<li>Suppress remaining <code>WordPress.DB.PreparedSQL.InterpolatedNotPrepared<\/code> warnings on the legacy-table RENAME \/ DROP queries (table names cannot be passed as prepared placeholders)<\/li>\n<li>Scope <code>uninstall.php<\/code> cleanup loop in a closure so its variables are no longer flagged as unprefixed globals<\/li>\n<\/ul>\n\n<h4>3.0.0<\/h4>\n\n<ul>\n<li>Renamed plugin to \"Gridirontables AFVD\" (third rename) to match the WordPress.org plugin slug <code>gridirontables-afvd<\/code><\/li>\n<li>Text domain changed to <code>gridirontables-afvd<\/code> (hyphenated, as required by WordPress.org)<\/li>\n<li>New shortcodes <code>[gridirontables_afvd_standings]<\/code> and <code>[gridirontables_afvd_schedule]<\/code>; previous <code>[dsfooboo_football_data_*]<\/code>, <code>[footballdata_*]<\/code> and <code>[afvdata_*]<\/code> shortcodes still work as aliases<\/li>\n<li>All internal prefixes (classes, options, CSS, AJAX hooks, cron hook) renamed to <code>gridirontables_afvd_*<\/code><\/li>\n<li>Migration on activation\/load handles tables and options from all three prior prefixes (<code>dsfooboo_football_data_*<\/code>, <code>footballdata_*<\/code>, <code>afvdata_*<\/code>)<\/li>\n<li>DB schema bumped to 1.3<\/li>\n<\/ul>\n\n<h4>2.5.2<\/h4>\n\n<ul>\n<li>Updated tagline to \"League tables &amp; schedules - data provided by AFVD\"<\/li>\n<\/ul>\n\n<h4>2.5.1<\/h4>\n\n<ul>\n<li>GitHub repository renamed from <code>footballdata<\/code> to <code>dsfooboo-football-data<\/code>; Plugin URI and documentation links updated accordingly<\/li>\n<\/ul>\n\n<h4>2.5.0<\/h4>\n\n<ul>\n<li>Renamed plugin to \"DSFOOBOO Football Data\"<\/li>\n<li>New shortcodes <code>[dsfooboo_football_data_standings]<\/code> and <code>[dsfooboo_football_data_schedule]<\/code>; previous <code>[footballdata_*]<\/code> and <code>[afvdata_*]<\/code> shortcodes still work as aliases<\/li>\n<li>All internal prefixes (classes, options, CSS, AJAX hooks, text domain, cron hook) renamed to <code>dsfooboo_football_data_*<\/code><\/li>\n<li>Migration on activation\/load handles tables and options from both prior prefixes (<code>footballdata_*<\/code> and <code>afvdata_*<\/code>)<\/li>\n<li>DB schema bumped to 1.2<\/li>\n<\/ul>\n\n<h4>2.4.1<\/h4>\n\n<ul>\n<li>GitHub repository renamed from <code>afvdata<\/code> to <code>footballdata<\/code>; Plugin URI and documentation links updated accordingly<\/li>\n<\/ul>\n\n<h4>2.4.0<\/h4>\n\n<ul>\n<li>Renamed plugin from \"AFVData\" to \"FootballData\"<\/li>\n<li>New shortcodes <code>[footballdata_standings]<\/code> and <code>[footballdata_schedule]<\/code>; old <code>[afvdata_*]<\/code> shortcodes still work as aliases<\/li>\n<li>All internal prefixes renamed from <code>afvdata<\/code> to <code>footballdata<\/code><\/li>\n<li>Automatic one-time migration on activation: renames database tables and copies options from the old prefix<\/li>\n<li>DB schema bumped to 1.1<\/li>\n<\/ul>\n\n<h4>2.3.0<\/h4>\n\n<ul>\n<li>Complete rename of all internal prefixes to afvdata<\/li>\n<li>Shortcodes are now <code>[afvdata_standings]<\/code> and <code>[afvdata_schedule]<\/code><\/li>\n<li>Text domain changed to <code>afvdata<\/code><\/li>\n<li>Updated all CSS classes, option names, and hook names<\/li>\n<li>Added Info tab with disclaimer and contact information<\/li>\n<li>Added plugin logo<\/li>\n<\/ul>\n\n<h4>2.1.0<\/h4>\n\n<ul>\n<li>Fixed schedule showing only own team's games<\/li>\n<li>Per-league team name configuration<\/li>\n<li>Configurable table colors with theme palette<\/li>\n<li>Top-level admin menu<\/li>\n<li>Raw data viewer on import tab<\/li>\n<li>Auto-detect groups from imported data<\/li>\n<li>German date format for schedule<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<\/ul>","raw_excerpt":"Display American football league standings and schedules from publicly available XML data on your WordPress site.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/305260","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=305260"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/dsfooboo"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=305260"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=305260"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=305260"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=305260"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=305260"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=305260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}