Template Conditions

Conditions let you show different programme content based on game context. Instead of a single static description, you can have multiple options that trigger based on specific situations — and each option can also override the programme title and subtitle.

How Conditions Work

Each condition option has:

  • Condition: What to check (e.g., is_home, win_streak)
  • Value: For numeric conditions, the threshold (e.g., 5 for a 5-game streak)
  • Priority: Lower numbers = higher priority (1-99 for conditionals, 100 for defaults)
  • Template: The description to use if the condition matches
  • Title / Subtitle Override (optional): replace the programme title and/or subtitle when this condition matches — e.g. put a bowl name or {game_event_note} in the title for marquee games
  • Label (optional): a display name for the row, shown in the editor

When generating EPG, Teamarr evaluates all conditions and selects the highest-priority (lowest number) match. If multiple conditions match at the same priority, one is chosen randomly.

In the template editor, each row carries a live trace badge driven by the selected preview event — green when the row fires (it’s the winner), amber when it matched but lost to a higher-priority row, muted when it doesn’t match — with a reason line explaining why. Condition names are advisory-validated as you type, like variables.

Conditions tab — preset library, prioritized rows with a live "fires" badge, and the Guide Preview

The picker offers a different set per template type. Event templates get everything except the “our team” perspective conditions (is_home, is_away, win_streak, loss_streak, is_ranked, is_ranked_opponent, opponent_name_contains) — those need a subscribed team, and event channels are positional. Team templates get the full list.

Condition presets

A set of condition rows can be saved as a reusable preset from the Conditions tab — save the current rows under a name, then apply (or delete) presets from the same menu on any other template. Applying a preset replaces the tab’s rows with the preset’s.

Title and subtitle selection

Titles and subtitles are selected per field, independently: for each field, the highest-priority matching row that defines that field wins. A row that only sets a title leaves the description to lower-priority rows (and vice versa), and any field with no matching override falls back to the template’s plain title/subtitle/description. Unlike descriptions, ties at the same priority resolve deterministically (first row wins) for titles and subtitles, so guide titles don’t change between EPG runs.

Example — a marquee-game row that rewrites the whole guide entry:

{"condition": "has_event_note", "priority": 15,
 "title": "{game_event_note}: {away_team} at {home_team}",
 "subtitle": "{venue} · {venue_city}",
 "template": "{game_event_note}. {away_team} take on {home_team} at {venue}."}

Priority System

Priority Purpose
1-49 High priority conditionals (rare situations)
50-99 Normal priority conditionals
100 Default fallback (always matches)

Lower numbers win. A priority 10 condition beats priority 50, which beats priority 100.

Filler Condition Rows

The same row mechanism drives the filler registers (pregame, postgame, and idle) on the Fillers tab. Filler rows use the identical shape and per-field selection rules as the main condition rows, with two filler-specific twists:

Reference game. Fillers have no “current game”, so each register’s rows evaluate against its natural reference: pregame → the next game, postgame and idle → the last game. Postgame and idle refresh the game’s status from the provider before evaluating, so is_final reflects reality even when the cached schedule is stale. On event channels, both registers evaluate against the channel’s event. Remember the variable suffix that goes with the reference: a team-template postgame row reads the last game via .last ({game_recap.last}), while event-template rows use the bare form ({game_recap}).

Description cascade. A winning row’s description that resolves to an empty string — the classic case is {game_recap} for a game that just ended, before the provider publishes a recap — falls through to the next matching row by priority, and finally to the register’s base description. Fields no matching row sets always fall back to the register’s base content.

The recap-first pattern (what new templates and the starter set ship):

[{"condition": "has_recap", "priority": 10, "template": "{game_recap.last}"},
 {"condition": "is_not_final", "priority": 50,
  "template": "The game between {team_name_the} and {opponent_the.last} has not yet ended."}]

Recap published → it renders verbatim. Game still running → the in-progress line. Final but no recap → neither row fires and the base register’s constructed result line renders.

The idle register’s no-schedule override (no upcoming game in the lookahead) stays separate from condition rows. It applies both in the off-season and when a provider has not published a schedule. Each enabled title, subtitle, or description field replaces only its corresponding normal idle field. Condition rows need a reference game to evaluate.


Available Conditions

Home/Away

Condition Value Description
is_home - Team is playing at home
is_away - Team is playing away/on the road

Example:

{"condition": "is_home", "priority": 50, "template": "{team_name} hosts {opponent} at {venue}"}
{"condition": "is_away", "priority": 50, "template": "{team_name} travels to face {opponent}"}

Streaks

Condition Value Description
win_streak Minimum streak length Team is on a winning streak >= value
loss_streak Minimum streak length Team is on a losing streak >= value

Example:

{"condition": "win_streak", "condition_value": "5", "priority": 10, "template": "🔥 {team_name} riding a {win_streak}-game win streak!"}
{"condition": "loss_streak", "condition_value": "3", "priority": 20, "template": "{team_name} looking to snap a {loss_streak}-game skid"}

Rankings (College)

Condition Value Description
is_ranked - Team is ranked (top 25)
is_ranked_opponent - Opponent is ranked (top 25)
is_ranked_matchup - Both teams are ranked (top 25)
is_top_ten_matchup - Both teams are in the top 10

Example:

{"condition": "is_top_ten_matchup", "priority": 5, "template": "🏆 Top 10 showdown! {team_rank_display} {team_name} vs {opponent_rank_display} {opponent}"}
{"condition": "is_ranked_matchup", "priority": 15, "template": "Ranked matchup: {team_rank_display} {team_name} vs {opponent_rank_display} {opponent}"}
{"condition": "is_ranked_opponent", "priority": 30, "template": "{team_name} faces {opponent_rank_display} {opponent}"}

Season Type

Condition Value Description
is_playoff - Playoff/postseason game
is_preseason - Preseason/exhibition game

Example:

{"condition": "is_playoff", "priority": 5, "template": "🏆 PLAYOFF: {team_name} vs {opponent}"}
{"condition": "is_preseason", "priority": 50, "template": "Preseason: {team_name} vs {opponent}"}

Neutral Site

Condition Value Description
is_neutral_site - Game is at a neutral site (bowls, CFP/NCAA tournament rounds, showcase games)

Host framing (“X travel to…”, “Y host X…”) misrepresents a game nobody hosts — branch to neutral prose instead. The {at_vs} / {vs_at} / {vs_@} connector variables also read vs automatically at neutral sites, so subtitles flip without a condition.

Example:

{"condition": "is_neutral_site", "priority": 17, "template": "{away_team} and {home_team} meet at {venue}."}

Conference (College)

Condition Value Description
is_conference_game - Both teams are in the same conference

Example:

{"condition": "is_conference_game", "priority": 40, "template": "{college_conference} matchup: {team_name} vs {opponent}"}

Broadcast

Condition Value Description
is_national_broadcast - Game is on national TV (ABC, CBS, NBC, FOX, ESPN, ESPN2, TNT, TBS)

Example:

{"condition": "is_national_broadcast", "priority": 60, "template": "{team_name} vs {opponent} on {broadcast_network}"}

Odds

Condition Value Description
has_odds - Betting odds are available for this game

Example:

{"condition": "has_odds", "priority": 70, "template": "{team_name} ({odds_spread}) vs {opponent}. O/U: {odds_over_under}"}

Game State

Condition Value Description
is_final - The reference game is final
is_not_final - The reference game exists but is not final yet

Both return false when there is no reference game at all. They’re a deliberate pair rather than one condition and its negation: rows for “game over” and “game still going” stay independent, so a field one row doesn’t set falls through to your defaults instead of leaking from the other state.

These shine in filler condition rows, where the reference game is the register’s next/last game with freshly-checked status.


Provider Copy (ESPN)

Condition Value Description
has_preview - Provider preview blurb is available (populates same-day pregame)
has_generated_preview - Optional generated preview is available from typed provider facts
has_recap - Provider recap headline is available (populates once the game is final)
has_structured_preview - Recent-form data is available (populates days ahead)
has_event_note - Marquee/playoff note is available (NBA Finals - Game 5, CFP Quarterfinal at the Cotton Bowl Classic); empty for ordinary games
has_match_note - Soccer competition note is available (FIFA World Cup, Group C); soccer only

Use these to prefer ESPN’s editorial copy and fall back to constructed prose when it isn’t published yet — the pattern the starter templates ship with:

Example:

[
  {"condition": "has_preview", "priority": 10, "template": "{game_preview}"},
  {"condition": "has_event_note", "priority": 15, "template": "{game_event_note}. {team_name} vs {opponent} at {venue}"},
  {"priority": 100, "template": "{team_name} vs {opponent} at {venue}"}
]

Opponent

Condition Value Description
opponent_name_contains Search string Opponent name contains the specified text (case-insensitive)

Example:

{"condition": "opponent_name_contains", "condition_value": "Rival", "priority": 20, "template": "🔥 Rivalry game! {team_name} vs {opponent}"}

League / Sport

Condition Value Description
league_is League code(s), comma-separated Event’s league matches one of the given codes (case-insensitive), e.g. cfb or cfb,nfl
sport_is Sport code(s), comma-separated Event’s sport matches one of the given codes (case-insensitive), e.g. football,basketball

Available to both team and event templates — one template can branch its description by league or sport instead of needing a separate template variant per league.

Example:

{"condition": "league_is", "condition_value": "cfb", "priority": 15, "template": "College football: {away_team} at {home_team}"}

Combat Sports (UFC/Boxing)

Result-based conditions for the headline bout — all false until the fight is final. Pair them with the Fight Results variables in postgame filler.

Condition Value Description
is_knockout - Fight ended by KO or TKO
is_submission - Fight ended by submission
is_decision - Fight went to a decision (any kind)
is_finish - Fight ended in a finish (KO/TKO/submission — not a decision)
went_distance - Fight went all scheduled rounds

Example:

{"condition": "is_finish", "priority": 10, "template": "{fighter1} def. {fighter2} — {fight_summary}"}
{"condition": "is_decision", "priority": 20, "template": "{fighter1} def. {fighter2} by {fight_result} ({judge_scores})"}

Motorsports

Session-aware conditions for racing templates, where each channel covers one session of a race weekend.

Condition Value Description
is_race_session - This channel’s session is the race itself
is_qualifying_session - This channel’s session is qualifying (or sprint qualifying)
has_results - This channel’s session has finished with results

Example:

{"condition": "has_results", "priority": 10, "template": "{session_name} results: {race_winner} wins the {race_name}"}
{"condition": "is_race_session", "priority": 50, "template": "The {race_name} from {circuit_name}"}

Default Descriptions

Priority 100 is reserved for default descriptions that always match. You should always have at least one default as a fallback.

{"priority": 100, "template": "{team_name} vs {opponent}"}

If you have multiple defaults (all at priority 100), one is chosen randomly - useful for variety.


Complete Example

Here’s a complete set of conditions for a college football team template:

[
  {"condition": "is_playoff", "priority": 5, "template": "🏆 PLAYOFF: {team_name} vs {opponent}"},
  {"condition": "is_top_ten_matchup", "priority": 10, "template": "🔥 Top 10 clash! {team_rank_display} {team_name} vs {opponent_rank_display} {opponent}"},
  {"condition": "win_streak", "condition_value": "5", "priority": 15, "template": "{team_name} riding a {win_streak}-game win streak vs {opponent}"},
  {"condition": "is_ranked_matchup", "priority": 20, "template": "Ranked matchup: {team_rank_display} {team_name} vs {opponent_rank_display} {opponent}"},
  {"condition": "is_ranked_opponent", "priority": 30, "template": "{team_name} faces {opponent_rank_display} {opponent}"},
  {"condition": "is_conference_game", "priority": 40, "template": "{college_conference} game: {team_name} vs {opponent}"},
  {"condition": "is_home", "priority": 50, "template": "{team_name} hosts {opponent} at {venue}"},
  {"condition": "is_away", "priority": 50, "template": "{team_name} travels to face {opponent}"},
  {"priority": 100, "template": "{team_name} vs {opponent}"}
]

Evaluation walks the priorities from lowest number to highest; the priority-100 default is the guaranteed fallback. Description ties at the same priority are chosen randomly (titles and subtitles pick the first row deterministically).


Back to top

Teamarr - Sports EPG Generator for Dispatcharr

This site uses Just the Docs, a documentation theme for Jekyll.