Introduction
WP SailingFlow is a complete race-management toolkit for sailing clubs that run PHRF handicap racing — installed as a single WordPress plugin on your own site.
It organizes your racing calendar and fleets, calculates corrected times and World Sailing Low-Point scores, and renders schedules, scratch sheets, individual race results, and series standings on your public pages through shortcodes. Everything lives in your WordPress admin — no spreadsheets, no separate scoreboard service, and no second login for your race committee.
This guide walks through installing the plugin, modelling your season, registering boats, entering finish times, and publishing the results.
Requirements
- WordPress 6.0 or newer
- PHP 7.4 or newer
- An administrator account, or any user granted the
manage_sailing_flowcapability
WP SailingFlow is self-contained: it bundles its own autoloader and assets, so there is nothing to compile and no Composer step to run on your server.
Installation
- Download the plugin zip from your account (or install the free edition from the WordPress.org directory once available).
- Upload it in your WordPress admin under Plugins → Add New → Upload Plugin, then choose the
wp-sailing-flow.zipfile. - Activate the plugin. On activation it creates its database tables and seeds a default division list (Spinnaker and Jib & Main).
- Open SailingFlow in the admin sidebar to reach the dashboard.
Schema updates apply automatically after an in-place plugin update, so you never have to deactivate and reactivate to pick up new fields.
Core concepts
WP SailingFlow models a club's racing as a four-level hierarchy. Understanding it makes everything else fall into place.
| Level | What it is | Example |
|---|---|---|
| Overall Season | A calendar year of racing. | 2026 |
| Racing Series | A scored campaign within a season. Carries the scoring method and throwout schedule, and owns the scratch sheet. | 2026 Summer Series |
| Regatta | A grouping of races that becomes one column in the series standings. | North Shore Regatta |
| Race | A single race on a date. Carries finish times and results. | Race 3 · Jul 12 |
A few things worth knowing:
- The public schedule is driven by the race date, not by membership — every dated race appears on its year's schedule, including schedule-only events like practices and socials.
- A boat keeps its identity across seasons. Its division, sail number, and PHRF rating are stored per Racing Series, so a boat can move divisions or change ratings between seasons without losing its history.
- Stand-alone scored races belong to no series or regatta. They carry their own roster and scoring settings, get their own results page, and never appear in any standings.
The admin menu
After activation you'll find a SailingFlow menu in the WordPress sidebar with these screens:
| Screen | What you do there |
|---|---|
| Dashboard | An at-a-glance overview and quick links into the rest of the plugin. |
| Overall Seasons | Create the years you race. |
| Racing Series | Define each scored series, its scoring method, and its throwout schedule. |
| Regattas | Create regattas — the standings columns within a series. |
| Races | Add individual races and assign them to a season, series, and regatta. |
| Enter Results | Enter finish times, set conditions, and publish a race's results. |
| Divisions | Manage your fleet's division list. |
| Boats | Maintain the master boat registry. |
| Scratch Sheet | Register boats into a series with their division, sail number, and PHRF rating. |
| Settings | Configure club name, page URLs, email recipients, and licensing. |
Your first season
A typical setup, start to finish:
- Create an Overall Season for the year (e.g. 2026).
- Add a Racing Series to that season. Choose its scoring method and, if you run a long series, set up throwouts.
- Create one or more Regattas under the series — each becomes a column in the standings.
- Register your fleet on the Scratch Sheet, giving every boat a division, sail number, and PHRF rating for the series.
- Add Races and assign each to the season, series, and regatta it belongs to.
- Publish your pages by placing the shortcodes (below) on a schedule page, a standings page, and so on.
From there your race-night routine is just Enter Results after each race.
Divisions & boats
Divisions are a fully managed list. The plugin seeds two to match the common model — Spinnaker (S) and Jib & Main (M) — but you can rename, add, or remove them to fit your club.
Boats live in a master registry with their own identity. A boat's competitive details — division, sail number, and PHRF rating — are not stored on the boat itself; they're stored on its registration in a series. That separation is what lets a boat change divisions or ratings between seasons while keeping a single, continuous history.
The scratch sheet
The scratch sheet is the boat roster of a Racing Series. Registering a boat there records its division, sail number, and PHRF rating for that series. Because registrations are per-series:
- A boat's Summer and Fall ratings or divisions can differ.
- A boat can be entered in two divisions within one series if your club allows it.
- Publishing the scratch sheet with
[wpsf_scratch_sheet]shows the registered boats grouped by division.
Entering results
Open Enter Results, pick the race, and enter each boat's finish time. The plugin computes elapsed and corrected times and assigns points automatically. A few things to know:
- Results stay editable after you submit them — fix a typo or a protest outcome anytime and the standings recalculate.
- Conditions and notes can be recorded per race and surface on the race-details view.
- Cancelled races are marked cancelled (not scored), kept off the standings, and shown as cancelled on the schedule with the reason in a tooltip.
- Clear Results is a confirmed do-over: it removes all results and per-division parameters for a race and resets its status to Scheduled, while keeping the race itself.
- For a stand-alone race, you also pick the boats and set each one's division, PHRF, and sail number right on this screen.
How scoring works
WP SailingFlow scores PHRF handicap racing under the Racing Rules of Sailing 2025–2028.
- Corrected time is calculated by time-on-distance by default. Time-on-time scoring (
Corrected = Elapsed × A / (B + PHRF), with editable A/B factors) is available per series. Pro - Points use the World Sailing Low-Point system (RRS A4): first place scores 1 point, second 2, and so on.
- Non-finishers are scored under RRS A5.2 (entries + 1) by default. An optional A5.3 mode scores a boat that came to the start but didn't finish against the number of boats that came, rather than the full entry list. Pro
- Ties in a single race are averaged per RRS A7; series ties are broken per RRS Appendix A8.
Time-on-distance scoring and standard A5.2 non-finisher scoring are free. Time-on-time and A5.3 are Pro options you can enable per series.
Standings & throwouts
Standings are produced per Racing Series, with one column per Regatta showing each boat's net total in that regatta.
Throwouts let you drop a boat's worst races once enough have been sailed. Pro A series can define a tiered schedule — for example, drop 1 after 8 races and 2 after 10. The plugin applies the largest tier whose race threshold has been reached (counted across all regattas in the series), shows the reduction in the regatta column as (−n), and never drops so many that a boat scores nothing. A non-excludable disqualification (DNE) is never dropped, as the rules require.
On phones, the standings keep the Place and Boat columns frozen while the score columns scroll horizontally, so boats stay easy to read.
Scoring codes
In addition to a finish time, you can mark a boat with any standard RRS scoring abbreviation. All are scored under RRS A5.2 (entries + 1) unless A5.3 is enabled.
| Code | Meaning |
|---|---|
DNF | Did not finish |
DNS | Did not start (came to the starting area) |
DNC | Did not come to the starting area |
OCS | On the course side at the start; did not start correctly |
RET | Retired after finishing |
NSC | Did not sail the course |
RAF | Retired after finishing |
DSQ | Disqualified (excludable by a throwout) |
DNE | Disqualification not excludable — never dropped by a throwout |
Shortcodes
Place any of these on a WordPress page or post to render that view. They produce responsive, theme-aware output and stay in sync with your data automatically.
| Shortcode | Renders | Attributes |
|---|---|---|
[wpsf_schedule] | The season race schedule. | year — defaults to the current year |
[wpsf_scratch_sheet] | Registered boats by division. | series (required, or from the URL) |
[wpsf_standings] | Full series standings, one column per regatta. | series, or regatta for a single regatta |
[wpsf_race_results] | The results of one race. | race (required, or from the URL) |
[wpsf_race_details] | Course & conditions for one race. | race (required, or from the URL) |
[wpsf_series_title] | A standings breadcrumb heading. | series |
[wpsf_breadcrumbs] | A navigation trail from the current URL. | year |
For example, a standings page for your summer series:
[wpsf_series_title series="4"]
[wpsf_standings series="4"]
Or a single regatta's standings:
[wpsf_standings regatta="12"]
URL parameters
Several shortcodes can take their context from the page URL instead of a fixed attribute, which is what makes a single results page work for every race. The plugin's own links use these automatically:
?wpsf_race=— for[wpsf_race_results]and[wpsf_race_details]?wpsf_series=— for[wpsf_scratch_sheet],[wpsf_series_title], and[wpsf_standings]?wpsf_regatta=— for a single regatta in[wpsf_standings]?year=— for[wpsf_schedule]
A URL parameter, when present, takes precedence over the matching shortcode attribute.
Legacy tags
If you're upgrading from a 1.x install, the old shortcode tags remain registered as aliases, so existing pages keep working without edits:
| Legacy tag | Current equivalent |
|---|---|
[SeasonSchedule] | [wpsf_schedule] |
[ScratchSheet] | [wpsf_scratch_sheet] |
[ShowSeriesTitle] | [wpsf_series_title] |
[RaceResults] | [wpsf_race_results] |
[RaceDetails] | [wpsf_race_details] |
[show_series_standings] | [wpsf_standings] |
The standings shortcode also accepts the old cup="ID" attribute and ?wpsf_cup= parameter as aliases for regatta.
Free vs Pro
The full race-management workflow — seasons, series, regattas, races, divisions, boats, the scratch sheet, time-on-distance scoring, stand-alone races, and every shortcode — is free. Pro adds:
- Tiered series throwouts
- Time-on-Time scoring
- RRS A5.3 penalty scoring
- Automatic result & cancellation emails, with one-click per-recipient unsubscribe
Your settings and data are never deleted. If a Pro license lapses, the Pro features simply pause; activate a license again and they switch back on instantly against your existing data.
Troubleshooting
A shortcode shows nothing
Most shortcodes need to know which series or race to render. Make sure you've passed the right series / race attribute, or that the page URL carries the matching ?wpsf_… parameter. An unknown or empty ID renders nothing rather than an error.
A race isn't on the schedule
The schedule is built from race dates by year. Confirm the race has a date in the year you're viewing — membership in a series is not required to appear.
Standings look wrong after editing a result
Standings recalculate when results are saved. Re-open Enter Results for the affected race, confirm the finish times and codes, and save again to force a recalculation.
A Pro feature isn't available
Throwouts, Time-on-Time, A5.3, and result emails require an active Pro license. Check the license status on the Settings screen.
Still stuck?
Reach out and we'll help you get your club's results published.