Add configurable printable venue labels

This commit is contained in:
2026-03-29 09:32:41 -05:00
parent d2ff863ca5
commit e019bf2061
4 changed files with 257 additions and 8 deletions

View File

@@ -260,7 +260,7 @@ body {
.event { .event {
--event-top-band: calc(var(--corner-badge-size, 11px) + var(--corner-badge-offset, 2px)); --event-top-band: calc(var(--corner-badge-size, 11px) + var(--corner-badge-offset, 2px));
--event-bottom-band: 14px; --event-bottom-band: 26px;
--event-logo-height: var(--pc-event-logo-height); --event-logo-height: var(--pc-event-logo-height);
position: relative; position: relative;
background: var(--event-bg, var(--team-primary, #1b76d1)); background: var(--event-bg, var(--team-primary, #1b76d1));
@@ -351,21 +351,50 @@ body {
color: #111; color: #111;
} }
.event-time { .event-meta {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
bottom: 2px; bottom: 2px;
z-index: 3; z-index: 3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
gap: 1px;
padding: 0 2px;
overflow: hidden;
}
.event-time {
order: 1;
max-width: 100%;
font-size: calc(12px * var(--month-font-scale)); font-size: calc(12px * var(--month-font-scale));
font-weight: 800; font-weight: 800;
line-height: 1; line-height: 1;
text-transform: uppercase; text-transform: uppercase;
text-align: center; text-align: center;
color: currentColor; color: currentColor;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
opacity: 0.95; opacity: 0.95;
} }
.event-venue {
order: 2;
max-width: 100%;
font-size: calc(8px * var(--month-font-scale));
font-weight: 700;
line-height: 1;
text-align: center;
text-transform: uppercase;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
opacity: 0.88;
}
.empty { .empty {
padding: 16px; padding: 16px;
border: 2px dashed #c8d2de; border: 2px dashed #c8d2de;

View File

@@ -229,6 +229,7 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
'sync_interval_minutes' => isset( $existing['sync_interval_minutes'] ) ? absint( (string) $existing['sync_interval_minutes'] ) : 60, 'sync_interval_minutes' => isset( $existing['sync_interval_minutes'] ) ? absint( (string) $existing['sync_interval_minutes'] ) : 60,
'venue_color_overrides' => $this->sanitize_venue_color_overrides( isset( $current['venue_color_overrides'] ) ? $current['venue_color_overrides'] : array() ), 'venue_color_overrides' => $this->sanitize_venue_color_overrides( isset( $current['venue_color_overrides'] ) ? $current['venue_color_overrides'] : array() ),
'venue_use_team_primary' => $this->sanitize_venue_primary_flags( isset( $current['venue_use_team_primary'] ) ? $current['venue_use_team_primary'] : array() ), 'venue_use_team_primary' => $this->sanitize_venue_primary_flags( isset( $current['venue_use_team_primary'] ) ? $current['venue_use_team_primary'] : array() ),
'printable_venue_label_mode' => $this->sanitize_venue_label_mode( isset( $current['printable_venue_label_mode'] ) ? $current['printable_venue_label_mode'] : '' ),
); );
} }
@@ -288,6 +289,17 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
echo '</select>'; echo '</select>';
echo '</td>'; echo '</td>';
echo '</tr>'; echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="asc-sp-printable-venue-label-mode">' . esc_html__( 'Venue Label Under Time', 'tonys-sportspress-enhancements' ) . '</label></th>';
echo '<td>';
echo '<select id="asc-sp-printable-venue-label-mode" name="' . esc_attr( self::OPTION_KEY . '[printable_venue_label_mode]' ) . '">';
foreach ( $this->get_venue_label_mode_options() as $mode => $label ) {
echo '<option value="' . esc_attr( $mode ) . '" ' . selected( $this->get_venue_label_mode(), $mode, false ) . '>' . esc_html( $label ) . '</option>';
}
echo '</select>';
echo '<p class="description">' . esc_html__( 'Choose whether the printable schedule shows the venue full name, abbreviation, or short name below each game time.', 'tonys-sportspress-enhancements' ) . '</p>';
echo '</td>';
echo '</tr>';
echo '</tbody></table>'; echo '</tbody></table>';
echo '<div style="margin:10px 0 14px;">'; echo '<div style="margin:10px 0 14px;">';
@@ -562,6 +574,7 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
'sync_interval_minutes' => 60, 'sync_interval_minutes' => 60,
'venue_color_overrides' => array(), 'venue_color_overrides' => array(),
'venue_use_team_primary'=> array(), 'venue_use_team_primary'=> array(),
'printable_venue_label_mode' => 'full_name',
); );
} }
@@ -574,6 +587,32 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
return wp_parse_args( get_option( self::OPTION_KEY, array() ), $this->default_settings() ); return wp_parse_args( get_option( self::OPTION_KEY, array() ), $this->default_settings() );
} }
/**
* Get supported venue label modes.
*
* @return array
*/
private function get_venue_label_mode_options() {
return array(
'full_name' => __( 'Full Name', 'tonys-sportspress-enhancements' ),
'abbreviation' => __( 'Abbreviation', 'tonys-sportspress-enhancements' ),
'short_name' => __( 'Short Name', 'tonys-sportspress-enhancements' ),
);
}
/**
* Sanitize venue label mode.
*
* @param mixed $value Raw value.
* @return string
*/
private function sanitize_venue_label_mode( $value ) {
$mode = is_string( $value ) ? sanitize_key( $value ) : '';
$allowed = array_keys( $this->get_venue_label_mode_options() );
return in_array( $mode, $allowed, true ) ? $mode : 'full_name';
}
/** /**
* Whether SportsPress is available. * Whether SportsPress is available.
* *
@@ -784,6 +823,17 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
return isset( $settings['venue_use_team_primary'] ) && is_array( $settings['venue_use_team_primary'] ) ? $settings['venue_use_team_primary'] : array(); return isset( $settings['venue_use_team_primary'] ) && is_array( $settings['venue_use_team_primary'] ) ? $settings['venue_use_team_primary'] : array();
} }
/**
* Get configured venue label mode.
*
* @return string
*/
private function get_venue_label_mode() {
$settings = $this->get_settings();
return $this->sanitize_venue_label_mode( isset( $settings['printable_venue_label_mode'] ) ? $settings['printable_venue_label_mode'] : '' );
}
/** /**
* Collect event entries for the calendar. * Collect event entries for the calendar.
* *
@@ -845,12 +895,14 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
} }
} }
$venues = get_the_terms( $event_id, 'sp_venue' ); $venue = $this->get_event_venue_term( $event_id );
$venue_name = ''; $venue_name = '';
$venue_id = 0; $venue_id = 0;
if ( is_array( $venues ) && isset( $venues[0] ) && is_object( $venues[0] ) && isset( $venues[0]->name ) ) { $venue_label = '';
$venue_name = (string) $venues[0]->name; if ( $venue ) {
$venue_id = isset( $venues[0]->term_id ) ? (int) $venues[0]->term_id : 0; $venue_name = (string) $venue->name;
$venue_id = (int) $venue->term_id;
$venue_label = $this->get_configured_venue_label( $venue );
} }
$entries[] = array( $entries[] = array(
@@ -863,6 +915,7 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
'opponent_name' => $opponent_id > 0 ? $this->get_team_label( $opponent_id ) : __( 'TBD', 'tonys-sportspress-enhancements' ), 'opponent_name' => $opponent_id > 0 ? $this->get_team_label( $opponent_id ) : __( 'TBD', 'tonys-sportspress-enhancements' ),
'event_time' => function_exists( 'sp_get_time' ) ? sp_get_time( $event_id ) : get_post_time( get_option( 'time_format' ), false, $event_id, true ), 'event_time' => function_exists( 'sp_get_time' ) ? sp_get_time( $event_id ) : get_post_time( get_option( 'time_format' ), false, $event_id, true ),
'venue_name' => $venue_name, 'venue_name' => $venue_name,
'venue_label' => $venue_label,
'venue_id' => $venue_id, 'venue_id' => $venue_id,
'venue_key' => $venue_id > 0 ? 'v:' . $venue_id : 'n:' . strtolower( $venue_name ), 'venue_key' => $venue_id > 0 ? 'v:' . $venue_id : 'n:' . strtolower( $venue_name ),
); );
@@ -983,7 +1036,12 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
} }
echo '</div>'; echo '</div>';
echo '<span class="ha-flag">' . esc_html( $is_home ? 'H' : 'A' ) . '</span>'; echo '<span class="ha-flag">' . esc_html( $is_home ? 'H' : 'A' ) . '</span>';
echo '<div class="event-meta">';
echo '<div class="event-time">' . esc_html( isset( $entry['event_time'] ) ? (string) $entry['event_time'] : '' ) . '</div>'; echo '<div class="event-time">' . esc_html( isset( $entry['event_time'] ) ? (string) $entry['event_time'] : '' ) . '</div>';
if ( ! empty( $entry['venue_label'] ) ) {
echo '<div class="event-venue" title="' . esc_attr( isset( $entry['venue_name'] ) ? (string) $entry['venue_name'] : '' ) . '">' . esc_html( (string) $entry['venue_label'] ) . '</div>';
}
echo '</div>';
echo '</article>'; echo '</article>';
} }
echo '</div>'; echo '</div>';
@@ -1023,6 +1081,51 @@ if ( ! class_exists( 'Tony_Sportspress_Printable_Calendars' ) ) {
return is_string( $title ) && '' !== $title ? $title : __( 'TBD', 'tonys-sportspress-enhancements' ); return is_string( $title ) && '' !== $title ? $title : __( 'TBD', 'tonys-sportspress-enhancements' );
} }
/**
* Get the first event venue term.
*
* @param int $event_id Event ID.
* @return WP_Term|null
*/
private function get_event_venue_term( $event_id ) {
$venues = get_the_terms( $event_id, 'sp_venue' );
if ( ! is_array( $venues ) || ! isset( $venues[0] ) || ! is_object( $venues[0] ) || ! isset( $venues[0]->term_id, $venues[0]->name ) ) {
return null;
}
return $venues[0];
}
/**
* Get the venue label for the current printable mode.
*
* Falls back to the full venue name when term meta is empty.
*
* @param WP_Term $venue Venue term.
* @return string
*/
private function get_configured_venue_label( $venue ) {
$full_name = isset( $venue->name ) ? trim( (string) $venue->name ) : '';
if ( '' === $full_name || ! isset( $venue->term_id ) ) {
return '';
}
$term_id = (int) $venue->term_id;
$mode = $this->get_venue_label_mode();
if ( 'abbreviation' === $mode ) {
$abbreviation = trim( (string) get_term_meta( $term_id, 'tse_abbreviation', true ) );
return '' !== $abbreviation ? $abbreviation : $full_name;
}
if ( 'short_name' === $mode ) {
$short_name = trim( (string) get_term_meta( $term_id, 'tse_short_name', true ) );
return '' !== $short_name ? $short_name : $full_name;
}
return $full_name;
}
/** /**
* Resolve venue color. * Resolve venue color.
* *

116
includes/sp-venue-meta.php Normal file
View File

@@ -0,0 +1,116 @@
<?php
/**
* Venue term metadata support.
*
* Adds short name and abbreviation fields to SportsPress venues.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Register venue term meta.
*/
function tony_sportspress_register_venue_term_meta() {
register_term_meta(
'sp_venue',
'tse_short_name',
array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'show_in_rest' => true,
'auth_callback' => static function() {
return current_user_can( 'manage_categories' );
},
)
);
register_term_meta(
'sp_venue',
'tse_abbreviation',
array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'show_in_rest' => true,
'auth_callback' => static function() {
return current_user_can( 'manage_categories' );
},
)
);
}
add_action( 'init', 'tony_sportspress_register_venue_term_meta' );
/**
* Render add-form fields for venue metadata.
*/
function tony_sportspress_add_venue_meta_fields() {
?>
<div class="form-field term-short-name-wrap">
<label for="tse_short_name"><?php esc_html_e( 'Short Name', 'tonys-sportspress-enhancements' ); ?></label>
<input name="tse_short_name" id="tse_short_name" type="text" value="" maxlength="100" />
<p><?php esc_html_e( 'Optional shorter label for this field or venue.', 'tonys-sportspress-enhancements' ); ?></p>
</div>
<div class="form-field term-abbreviation-wrap">
<label for="tse_abbreviation"><?php esc_html_e( 'Abbreviation', 'tonys-sportspress-enhancements' ); ?></label>
<input name="tse_abbreviation" id="tse_abbreviation" type="text" value="" maxlength="20" />
<p><?php esc_html_e( 'Optional abbreviation such as CC East or Field 1.', 'tonys-sportspress-enhancements' ); ?></p>
</div>
<?php
}
add_action( 'sp_venue_add_form_fields', 'tony_sportspress_add_venue_meta_fields' );
/**
* Render edit-form fields for venue metadata.
*
* @param WP_Term $term Venue term.
*/
function tony_sportspress_edit_venue_meta_fields( $term ) {
$short_name = get_term_meta( $term->term_id, 'tse_short_name', true );
$abbreviation = get_term_meta( $term->term_id, 'tse_abbreviation', true );
?>
<tr class="form-field term-short-name-wrap">
<th scope="row">
<label for="tse_short_name"><?php esc_html_e( 'Short Name', 'tonys-sportspress-enhancements' ); ?></label>
</th>
<td>
<input name="tse_short_name" id="tse_short_name" type="text" value="<?php echo esc_attr( $short_name ); ?>" maxlength="100" />
<p class="description"><?php esc_html_e( 'Optional shorter label for this field or venue.', 'tonys-sportspress-enhancements' ); ?></p>
</td>
</tr>
<tr class="form-field term-abbreviation-wrap">
<th scope="row">
<label for="tse_abbreviation"><?php esc_html_e( 'Abbreviation', 'tonys-sportspress-enhancements' ); ?></label>
</th>
<td>
<input name="tse_abbreviation" id="tse_abbreviation" type="text" value="<?php echo esc_attr( $abbreviation ); ?>" maxlength="20" />
<p class="description"><?php esc_html_e( 'Optional abbreviation such as CC East or Field 1.', 'tonys-sportspress-enhancements' ); ?></p>
</td>
</tr>
<?php
}
add_action( 'sp_venue_edit_form_fields', 'tony_sportspress_edit_venue_meta_fields' );
/**
* Save venue metadata fields.
*
* @param int $term_id Venue term ID.
*/
function tony_sportspress_save_venue_meta_fields( $term_id ) {
if ( ! current_user_can( 'manage_categories' ) ) {
return;
}
$short_name = isset( $_POST['tse_short_name'] ) ? sanitize_text_field( wp_unslash( $_POST['tse_short_name'] ) ) : '';
$short_name = is_string( $short_name ) ? trim( $short_name ) : '';
$abbreviation = isset( $_POST['tse_abbreviation'] ) ? sanitize_text_field( wp_unslash( $_POST['tse_abbreviation'] ) ) : '';
$abbreviation = is_string( $abbreviation ) ? trim( $abbreviation ) : '';
update_term_meta( $term_id, 'tse_short_name', $short_name );
update_term_meta( $term_id, 'tse_abbreviation', $abbreviation );
}
add_action( 'created_sp_venue', 'tony_sportspress_save_venue_meta_fields' );
add_action( 'edited_sp_venue', 'tony_sportspress_save_venue_meta_fields' );

View File

@@ -37,3 +37,4 @@ require_once plugin_dir_path(__FILE__) . 'includes/sp-event-admin-week-filter.ph
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-quick-edit-officials.php'; require_once plugin_dir_path(__FILE__) . 'includes/sp-event-quick-edit-officials.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-team-ordering.php'; require_once plugin_dir_path(__FILE__) . 'includes/sp-event-team-ordering.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-printable-calendars.php'; require_once plugin_dir_path(__FILE__) . 'includes/sp-printable-calendars.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-venue-meta.php';