'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' ); }, ) ); register_term_meta( 'sp_venue', 'tse_ground_rules', array( 'type' => 'string', 'single' => true, 'sanitize_callback' => 'wp_kses_post', 'show_in_rest' => true, 'auth_callback' => static function() { return current_user_can( 'manage_categories' ); }, ) ); } add_action( 'init', 'tony_sportspress_register_venue_term_meta' ); /** * Determine whether the field page should show its event list. * * The setting is stored in the core SportsPress Events settings page under * the venue/field section. * * @return bool */ function tony_sportspress_field_event_list_enabled() { $enabled = get_option( 'sportspress_event_show_venue_list', 'yes' ) === 'yes'; return (bool) apply_filters( 'tony_sportspress_field_event_list_enabled', $enabled ); } /** * Get the venue map caption text. * * @return string */ function tony_sportspress_get_venue_map_caption() { return (string) apply_filters( 'tony_sportspress_venue_map_caption', __( 'Field Map', 'tonys-sportspress-enhancements' ) ); } /** * Add the field page event list setting to SportsPress > Settings > Games > Fields. * * @param array $options Existing venue settings. * @return array */ function tony_sportspress_add_venue_settings( $options ) { $options[] = array( 'title' => esc_attr__( 'Event List', 'tonys-sportspress-enhancements' ), 'desc' => esc_attr__( 'Display event list on field pages', 'tonys-sportspress-enhancements' ), 'id' => 'sportspress_event_show_venue_list', 'default' => 'yes', 'type' => 'checkbox', ); return $options; } add_filter( 'sportspress_venue_options', 'tony_sportspress_add_venue_settings' ); /** * Enqueue the visual editor on the venue taxonomy screen. * * This turns the built-in description textarea into the standard WordPress * TinyMCE editor so venue descriptions can use markup and links. * * @param string $hook_suffix Current admin page hook. */ function tony_sportspress_enqueue_venue_description_editor( $hook_suffix ) { if ( ! in_array( $hook_suffix, array( 'edit-tags.php', 'term.php' ), true ) ) { return; } $taxonomy = isset( $_GET['taxonomy'] ) ? sanitize_key( wp_unslash( $_GET['taxonomy'] ) ) : ''; if ( 'sp_venue' !== $taxonomy ) { return; } if ( ! function_exists( 'wp_enqueue_editor' ) ) { return; } wp_enqueue_editor(); $script = <<<'JS' (function() { function initEditor(id) { var textarea = document.getElementById(id); if (!textarea || textarea.dataset.tseEditorInitialized) { return; } textarea.dataset.tseEditorInitialized = '1'; window.wp.editor.initialize(id, { tinymce: { wpautop: true, menubar: false, statusbar: true, toolbar1: 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,wp_more,spellchecker,fullscreen', toolbar2: 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help', block_formats: 'Paragraph=p; Heading 2=h2; Heading 3=h3; Heading 4=h4; Preformatted=pre', }, quicktags: true, mediaButtons: true }); } document.addEventListener('DOMContentLoaded', function() { if (!window.wp || !wp.editor) { return; } // Different taxonomy screens use different IDs for the same description field. initEditor('description'); initEditor('tag-description'); }); })(); JS; wp_add_inline_script( 'editor', $script ); } add_action( 'admin_enqueue_scripts', 'tony_sportspress_enqueue_venue_description_editor' ); /** * Hide the built-in venue archive description output. * * Venue content is rendered as SportsPress-style sections instead of inside * the archive header. * * @param string $description Archive description HTML. * @return string */ function tony_sportspress_hide_venue_archive_description( $description ) { if ( is_tax( 'sp_venue' ) ) { return ''; } return $description; } add_filter( 'get_the_archive_description', 'tony_sportspress_hide_venue_archive_description', 99 ); /** * Determine whether the current venue has map coordinates. * * @return bool */ function tony_sportspress_current_venue_has_map() { $term = get_queried_object(); if ( ! $term instanceof WP_Term ) { return false; } $latitude = trim( (string) get_term_meta( $term->term_id, 'sp_latitude', true ) ); $longitude = trim( (string) get_term_meta( $term->term_id, 'sp_longitude', true ) ); return '' !== $latitude && '' !== $longitude; } /** * Render the venue ground rules section. * * @return void */ function tony_sportspress_render_venue_ground_rules_section() { if ( ! is_tax( 'sp_venue' ) ) { return; } $term = get_queried_object(); if ( ! $term instanceof WP_Term ) { return; } $ground_rules = get_term_meta( $term->term_id, 'tse_ground_rules', true ); if ( ! is_string( $ground_rules ) || '' === trim( $ground_rules ) ) { return; } $ground_rules = apply_filters( 'the_content', $ground_rules ); echo '

' . esc_html__( 'Ground Rules', 'tonys-sportspress-enhancements' ) . '

' . $ground_rules . '
'; } add_action( 'sportspress_before_venue_map', 'tony_sportspress_render_venue_ground_rules_section', 5 ); /** * Open the venue map section wrapper. * * @return void */ function tony_sportspress_open_venue_map_section() { if ( ! is_tax( 'sp_venue' ) || ! tony_sportspress_current_venue_has_map() ) { return; } $GLOBALS['tse_venue_map_section_open'] = true; echo '

' . esc_html( tony_sportspress_get_venue_map_caption() ) . '

'; } add_action( 'sportspress_before_venue_map', 'tony_sportspress_open_venue_map_section', 15 ); /** * Close the venue map section wrapper. * * @return void */ function tony_sportspress_close_venue_map_section() { if ( empty( $GLOBALS['tse_venue_map_section_open'] ) ) { return; } $GLOBALS['tse_venue_map_section_open'] = false; echo '
'; } add_action( 'sportspress_after_venue_map', 'tony_sportspress_close_venue_map_section', 5 ); /** * Enqueue venue section styles. * * The venue map and ground rules are rendered as SportsPress-style sections * rather than archive header content, so they need section-scoped typography * and list styling. * * @return void */ function tony_sportspress_enqueue_venue_section_styles() { if ( ! is_tax( 'sp_venue' ) ) { return; } wp_register_style( 'tony-sportspress-venue-sections', false, array(), TONY_SPORTSPRESS_ENHANCEMENTS_VERSION ); wp_enqueue_style( 'tony-sportspress-venue-sections' ); $event_list_display = tony_sportspress_field_event_list_enabled() ? 'block' : 'none'; $css = <<

'tse_ground_rules', 'textarea_rows' => 10, 'media_buttons' => true, 'teeny' => false, 'quicktags' => true, 'drag_drop_upload' => true, ) ); ?>

term_id, 'tse_short_name', true ); $abbreviation = get_term_meta( $term->term_id, 'tse_abbreviation', true ); $ground_rules = get_term_meta( $term->term_id, 'tse_ground_rules', true ); ?>

'tse_ground_rules', 'textarea_rows' => 10, 'media_buttons' => true, 'teeny' => false, 'quicktags' => true, 'drag_drop_upload' => true, ) ); ?>