'', 'ride_type' => '', 'direction' => '', 'min_distance' => '', 'max_distance' => '', 'min_ascent' => '', 'max_ascent' => '', 'search' => '', 'search_scope' => 'title', 'activity_type' => '', 'route_category' => '', 'min_bearing' => '', 'max_bearing' => '', 'has_prompt_card' => '', 'has_external_links' => '', 'has_gpx' => '', 'visibility' => '', 'password' => '', // Display parameters 'show_filter' => 'true', 'show_grouping_toggle' => 'auto', 'group_similar' => 'auto', 'limit' => '0', 'layout' => 'grid', 'title' => '', 'description' => '', // Access control 'require_login' => 'false' ), $atts, 'rfcc_filtered_routes'); // Check login requirement if (filter_var($atts['require_login'], FILTER_VALIDATE_BOOLEAN) && !is_user_logged_in()) { return '
You must be logged in to view routes.
'; } // Convert string booleans $show_filter = filter_var($atts['show_filter'], FILTER_VALIDATE_BOOLEAN); $group_similar = $atts['group_similar'] === 'auto' ? get_option('rfcc_default_grouping', true) : filter_var($atts['group_similar'], FILTER_VALIDATE_BOOLEAN); // Handle show_grouping_toggle $show_grouping_toggle = $atts['show_grouping_toggle']; if ($show_grouping_toggle === 'auto') { $show_grouping_toggle = get_option('rfcc_filter_show_group_rides', 1); } else { $show_grouping_toggle = filter_var($show_grouping_toggle, FILTER_VALIDATE_BOOLEAN); } ob_start(); ?>

.rfcc-filtered-routes-container { margin: 20px 0; } .rfcc-filtered-routes-title { margin-bottom: 15px; } .rfcc-filtered-routes-description { margin-bottom: 20px; padding: 15px; background: #f9f9f9; border-left: 4px solid #0073aa; } .rfcc-filtered-routes-filter { margin-bottom: 20px; } .rfcc-login-required { background: #fff3cd; color: #856404; padding: 15px; border: 1px solid #ffeaa7; border-radius: 4px; margin: 20px 0; } do_item( 'rfcc-filtered-routes-style' ); ?> Filter dependencies not loaded. Please check plugin configuration.'; } $ranges = rfcc_get_route_ranges(); $club_groups = rfcc_get_club_groups(); ob_start(); ?>
$group) { $is_checked = in_array($key, $selected_groups, true); echo ''; } ?>
'; printf('', esc_attr($dir), esc_attr($checked)); printf('%s', esc_html($dir)); echo ''; } ?>
Route filtering function not available. Please ensure the route filter is properly configured.'; } /** * Enqueue scripts for filtered routes */ function rfcc_enqueue_filtered_routes_scripts() { // Ensure the function is available if (!function_exists('rfcc_enqueue_simple_route_filter_scripts')) { require_once RFCC_PLUGIN_PATH . 'frontend/route-group-filter.php'; } // Reuse existing route filter scripts if (function_exists('rfcc_enqueue_simple_route_filter_scripts')) { rfcc_enqueue_simple_route_filter_scripts(); } if (function_exists('rfcc_enqueue_clear_all_filters_script')) { rfcc_enqueue_clear_all_filters_script(); } } /** * Add login access control to existing shortcodes */ add_filter('rfcc_route_list_access_check', 'rfcc_check_route_list_access', 10, 2); function rfcc_check_route_list_access($allowed, $shortcode_atts) { $require_login = get_option('rfcc_require_login_for_routes', false); if ($require_login && !is_user_logged_in()) { return false; } return $allowed; } /** * Admin page for predefined filter helper * NOTE: This is now replaced by the combined shortcode management page */ // Disabled - using combined shortcode management instead // add_action('admin_menu', 'rfcc_add_predefined_filter_helper_menu'); function rfcc_add_predefined_filter_helper_menu() { add_submenu_page( 'edit.php?post_type=rfcc_route', 'Filter Shortcodes', 'Filter Shortcodes', RFCC_Permission_Manager::get_admin_menu_capability('rfcc-filter-shortcodes'), 'rfcc-filter-shortcodes', 'rfcc_predefined_filter_helper_page' ); } /** * Predefined filter helper admin page */ function rfcc_predefined_filter_helper_page() { ?>

Route Filter Shortcode Helper

Filtered Routes Shortcode

Create custom route lists with predefined filters:

Title
Description
Club Groups $group) { echo ''; } ?>
Ride Type
Direction '; echo ' '; echo esc_html($dir); echo ''; } ?>
Distance Range Min: Max:
Ascent Range Min: Max:
Search Term
Show Filter Box
Require Login
Result Limit

Generated Shortcode

Global Access Control

Require Login for Routes

When enabled, only logged-in users can see route lists unless overridden in individual shortcodes.

function rfccUpdateFilterShortcode() { const title = document.getElementById('rfcc-filter-title').value; const description = document.getElementById('rfcc-filter-description').value; const rideType = document.getElementById('rfcc-filter-ride-type').value; const minDistance = document.getElementById('rfcc-filter-min-distance').value; const maxDistance = document.getElementById('rfcc-filter-max-distance').value; const minAscent = document.getElementById('rfcc-filter-min-ascent').value; const maxAscent = document.getElementById('rfcc-filter-max-ascent').value; const search = document.getElementById('rfcc-filter-search').value; const showFilter = document.getElementById('rfcc-show-filter').checked; const requireLogin = document.getElementById('rfcc-require-login').checked; const limit = document.getElementById('rfcc-filter-limit').value; // Get selected club groups const clubGroups = Array.from(document.querySelectorAll('.rfcc-club-group-filter:checked')) .map(cb => cb.value).join(','); // Get selected directions const directions = Array.from(document.querySelectorAll('.rfcc-direction-filter:checked')) .map(cb => cb.value).join(','); let shortcode = '[rfcc_filtered_routes'; if (title) shortcode += ' title="' + title + '"'; if (description) shortcode += ' description="' + description + '"'; if (clubGroups) shortcode += ' club_groups="' + clubGroups + '"'; if (rideType) shortcode += ' ride_type="' + rideType + '"'; if (directions) shortcode += ' direction="' + directions + '"'; if (minDistance) shortcode += ' min_distance="' + minDistance + '"'; if (maxDistance) shortcode += ' max_distance="' + maxDistance + '"'; if (minAscent) shortcode += ' min_ascent="' + minAscent + '"'; if (maxAscent) shortcode += ' max_ascent="' + maxAscent + '"'; if (search) shortcode += ' search="' + search + '"'; if (!showFilter) shortcode += ' show_filter="false"'; if (requireLogin) shortcode += ' require_login="true"'; if (limit && limit !== '0') shortcode += ' limit="' + limit + '"'; shortcode += ']'; document.getElementById('rfcc-generated-filter-shortcode').value = shortcode; } function rfccCopyFilterShortcode() { const textarea = document.getElementById('rfcc-generated-filter-shortcode'); textarea.select(); document.execCommand('copy'); alert('Shortcode copied to clipboard!'); } // Add event listeners document.addEventListener('DOMContentLoaded', function() { const inputs = [ 'rfcc-filter-title', 'rfcc-filter-description', 'rfcc-filter-ride-type', 'rfcc-filter-min-distance', 'rfcc-filter-max-distance', 'rfcc-filter-min-ascent', 'rfcc-filter-max-ascent', 'rfcc-filter-search', 'rfcc-show-filter', 'rfcc-require-login', 'rfcc-filter-limit' ]; inputs.forEach(id => { const element = document.getElementById(id); if (element) { element.addEventListener('input', rfccUpdateFilterShortcode); element.addEventListener('change', rfccUpdateFilterShortcode); } }); // Add listeners for checkboxes document.querySelectorAll('.rfcc-club-group-filter, .rfcc-direction-filter').forEach(cb => { cb.addEventListener('change', rfccUpdateFilterShortcode); }); rfccUpdateFilterShortcode(); }); do_item( 'rfcc-filter-helper-page-js' ); } /** * Register access control settings */ add_action('admin_init', 'rfcc_register_access_control_settings'); function rfcc_register_access_control_settings() { register_setting('rfcc_access_control', 'rfcc_require_login_for_routes', array( 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'rest_sanitize_boolean' )); }