WP Manifestindependent plugin directory
manifest / unclassified / camaleaun-worldcup2026

WC2026 Schedule

FIFA World Cup 2026™ interactive schedule — WordPress Gutenberg block plugin (TypeScript + React)

by camaleaun · github.com/camaleaun/camaleaun-worldcup2026 · website

0stars
0forks

Install

The author publishes release zips, so WP-CLI can install straight from GitHub:

wp plugin install https://github.com/camaleaun/camaleaun-worldcup2026/releases/download/trunk/camaleaun-worldcup2026.zip

Readme

FIFA World Cup 2026™ Schedule

Interactive schedule as a Gutenberg block.
Calendar · Groups · Knockout bracket · Score entry · DB-backed · REST API

Contributors: camaleaun
Tags: fifa, world cup, soccer, schedule, block
Requires at least: 6.4
Tested up to: 6.8
Requires PHP: 8.0
Stable tag: trunk
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Interactive FIFA World Cup 2026™ schedule as a Gutenberg block — calendar, groups, knockout bracket and score entry.

Description

Full-featured World Cup schedule block with four views (Calendar, Matches, Groups, Knockout), live standings computed from entered scores, per-match sync from the plugin's own database, timezone support and local SVG flags for all 48 national teams.

Features

  • 🗓 Calendar — all 104 matches grouped by local date (timezone-aware). Sticky day headers, kick-off time, city and score button
  • 📋 Matches — filterable table with chips (All / Group Stage / Knockout / Group A–L). Responsive columns
  • 🏆 Groups — 12 group cards with live standings computed from entered scores + round switcher + match list per round
  • ⚔️ Knockout — full bracket (desktop: column layout / mobile: round tabs R32 / R16 / QF / SF / 🏆). Resolves team names as upstream results are entered
  • ✏️ Score entry — inline on any card: two goal inputs. Knockout draws: penalty shootout inputs
  • 💾 Persistence — localStorage (wc2026_scores_v1), survives page refresh, works offline
  • ⬇️ Per-match sync — REST endpoint lets admin enter official results; frontend can pull single match
  • 🏴 Flags — local SVG files (assets/flags/bra.svg etc.), no external CDN dependency at runtime
  • 🕐 Timezone — 29 common IANA timezones, persisted in localStorage

Database Schema

Five custom tables are created on activation under the {prefix}cwc26_ namespace. The schema mirrors the WordPress wp_posts + wp_postmeta and wp_terms + wp_term_taxonomy patterns for familiarity.

cwc26_teams

The 48 qualified national teams.

Column Type Notes
team_id BIGINT UNSIGNED AUTO_INCREMENT Primary key
fifa_code VARCHAR(4) UNIQUE NOT NULL Three-letter FIFA code (e.g. BRA)
flag_iso VARCHAR(10) ISO 3166-1 alpha-2 used when downloading flag SVG
name VARCHAR(100) NOT NULL English team name
ranking INT UNSIGNED FIFA ranking at time of draw

cwc26_stadiums

The 16 FIFA World Cup 2026™ venues.

Column Type Notes
stadium_id BIGINT UNSIGNED AUTO_INCREMENT Primary key
code VARCHAR(10) UNIQUE NOT NULL Short venue code (e.g. XII)
city VARCHAR(100) NOT NULL Host city
name VARCHAR(150) NOT NULL Full venue name

cwc26_groups

Pivot table mapping each team to its group-phase group.

Column Type Notes
group_id BIGINT UNSIGNED AUTO_INCREMENT Primary key
group_letter CHAR(1) NOT NULL AL
team_code VARCHAR(4) NOT NULL FK → cwc26_teams.fifa_code

cwc26_matches

The 104 scheduled matches.

Column Type Notes
match_id BIGINT UNSIGNED AUTO_INCREMENT Primary key
match_date DATETIME NOT NULL Kick-off in UTC
stadium_id BIGINT UNSIGNED FK → cwc26_stadiums.stadium_id
round VARCHAR(10) NOT NULL 1 / 2 / 3 (group) or r32 / r16 / qf / sf / f
phase VARCHAR(20) NOT NULL group or knockout
group_id VARCHAR(1) Group letter (AL); NULL for knockout
home_code VARCHAR(4) NOT NULL Home team FIFA code
away_code VARCHAR(4) NOT NULL Away team FIFA code
home_score INT Goals after 90 min; NULL until played
away_score INT Goals after 90 min; NULL until played
match_status VARCHAR(20) NOT NULL scheduled / live / finished

cwc26_matchmeta

Key-value metadata per match — mirrors the WordPress wp_postmeta pattern. Two own columns are meta_key + meta_value.

Column Type Notes
meta_id BIGINT UNSIGNED AUTO_INCREMENT Primary key
match_id BIGINT UNSIGNED NOT NULL FK → cwc26_matches.match_id
meta_key VARCHAR(255) NOT NULL e.g. home_penalties, away_penalties
meta_value LONGTEXT Serialized value

REST API

Base namespace: cwc26/v1

Method Endpoint Auth Description
GET /teams All 48 teams with flag_url
GET /stadiums All 16 venues
GET /matches All 104 matches (paginated, per_page supported)
GET /matches/{id} Single match by ID
POST /matches/{id}/score Editor+ Set home_score, away_score, match_status

Block Attributes

Attribute Type Default Description
defaultTab string calendar Which tab opens first
resultsUrl string GitHub raw URL URL for bulk results.json sync
align string wide Block alignment (wide or full)

i18n

  • .pot template generated with wp i18n make-pot
  • .po for pt_BR — 80+ strings including all 48 team names
  • .mo compiled and ready

Changelog

1.2.0

  • Add normalized DB tables (cwc26_*), REST API (cwc26/v1), DataViews admin page, per-match sync, and local SVG flags.

1.1.0

  • Add WordPress Playground blueprints and CI release workflow.

1.0.0

  • Initial release — block plugin with Calendar, Matches, Groups, and Knockout views, score entry and timezone support.

Upgrade Notice

1.0.0

Initial release.


Development

Requirements

Tool Version
Node.js ≥ 18
npm ≥ 9
PHP ≥ 8.0

Scripts

npm install          # install dependencies
npm run build        # production build → build/
npm run start        # development watch
npm run flags        # download flag SVGs → assets/flags/
npm run readme       # regenerate README.md from readme.txt
npm run check-types  # TypeScript type-check (no emit)

Source Structure

src/
├── index.tsx              # Block registration + editor preview
├── frontend.tsx           # Front-end entry — mounts React
├── App.tsx                # Root: tabs, timezone, sync
├── types.ts               # TypeScript interfaces
├── data.ts                # DB data helpers (getTeam, getStadium…)
├── utils.ts               # Datetime formatting + standings calc
├── hooks/
│   ├── useScores.ts       # localStorage state + REST sync
│   └── useTimezone.ts     # Timezone state + persistence
├── components/
│   ├── MatchCard.tsx      # Card used across all views
│   ├── MatchDetail.tsx    # Full match panel with score editing
│   └── ScoreInput.tsx     # Inline score form (goals + penalties)
├── views/
│   ├── CalendarView.tsx   # Day-grouped calendar
│   ├── MatchesView.tsx    # Filterable matches table
│   ├── GroupsView.tsx     # Groups grid → live standings
│   └── KnockoutView.tsx   # Bracket (desktop / mobile)
├── admin/
│   └── index.tsx          # WP admin DataViews page
├── frontend.css           # Front-end styles (dark navy + FIFA gold)
└── editor.css             # Editor-only preview styles

includes/
├── class-cwc26-db.php     # Table creation (dbDelta) + meta helpers
├── class-cwc26-seeder.php # Seeds all tables from src/data.json
├── class-cwc26-rest.php   # REST namespace cwc26/v1
└── class-cwc26-admin.php  # Admin menu page + script enqueue

scripts/
└── download-flags.mjs     # Downloads flag SVGs from flagcdn.com

Flag SVGs

Flag files live in assets/flags/ using lowercase FIFA codes (bra.svg, arg.svg, …). They are gitignored — download locally with npm run flags. The CI release workflow runs npm run flags automatically before creating the zip.

GitHub Sync — data/results.json format

Place this file at the raw URL configured in the block settings:

{
  "version": "1.0",
  "updated": "2026-06-11",
  "scores": {
    "1":  { "home": 2, "away": 0 },
    "73": { "home": 1, "away": 1, "homePenalties": 4, "awayPenalties": 3 }
  }
}
  • Key — match ID (1–104)
  • home / away — goals after 90 minutes
  • homePenalties / awayPenalties — penalty shootout, knockout draws only

Read the full README on GitHub →

Releases

TagPublishedAssetDownloads
trunk Jun 22, 2026 camaleaun-worldcup2026.zip 0