Changeset 3422278
- Timestamp:
- 12/17/2025 08:20:07 PM (4 months ago)
- Location:
- rainbow-slider/trunk
- Files:
-
- 4 added
- 1 edited
-
assets/swiper (added)
-
assets/swiper/swiper-bundle.min.css (added)
-
assets/swiper/swiper-bundle.min.js (added)
-
languages/rainbow-slider.pot (added)
-
rainbow-slider.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
rainbow-slider/trunk/rainbow-slider.php
r3422237 r3422278 17 17 */ 18 18 19 if ( ! defined( 'ABSPATH' ) ) { 20 exit; // Exit if accessed directly. 21 } 22 23 /** 24 * 1. Load Text Domain (Language Support) 25 */ 26 add_action( 'plugins_loaded', 'rainbow_slider_load_textdomain' ); 27 28 function rainbow_slider_load_textdomain() { 29 load_plugin_textdomain( 30 'rainbow-slider', 31 false, 32 dirname( plugin_basename( __FILE__ ) ) . '/languages' 33 ); 34 } 35 36 /** 37 * 2. Register Custom Post Type 38 */ 39 add_action( 'init', 'rainbow_slider_register_cpt' ); 40 41 function rainbow_slider_register_cpt() { 42 $labels = [ 43 'name' => __( 'Rainbow Sliders', 'rainbow-slider' ), 44 'singular_name' => __( 'Rainbow Slider', 'rainbow-slider' ), 45 'menu_name' => __( 'Rainbow Slider', 'rainbow-slider' ), 46 'add_new' => __( 'Add New Slider', 'rainbow-slider' ), 47 'add_new_item' => __( 'Add New Slider', 'rainbow-slider' ), 48 'edit_item' => __( 'Edit Slider', 'rainbow-slider' ), 49 'new_item' => __( 'New Slider', 'rainbow-slider' ), 50 'view_item' => __( 'View Slider', 'rainbow-slider' ), 51 'all_items' => __( 'All Sliders', 'rainbow-slider' ), 52 'search_items' => __( 'Search Sliders', 'rainbow-slider' ), 53 'not_found' => __( 'No sliders found', 'rainbow-slider' ), 54 'not_found_in_trash' => __( 'No sliders found in Trash', 'rainbow-slider' ), 55 ]; 19 if ( ! defined( 'ABSPATH' ) ) exit; 20 21 /*------------------------------------------------- 22 1. Register CPT 23 --------------------------------------------------*/ 24 add_action( 'init', function () { 56 25 57 26 register_post_type( 'rainbow', [ 58 'labels' => $labels, 59 'public' => true, 60 'show_in_rest' => true, 61 'menu_icon' => 'dashicons-images-alt2', 62 'supports' => [ 'title', 'editor' ], 63 'exclude_from_search' => true, 64 'publicly_queryable' => false, 65 'show_ui' => true, 27 'labels' => [ 28 'name' => 'Rainbow Sliders', 29 'singular_name' => 'Rainbow Slider', 30 'menu_name' => 'Rainbow Slider', 31 'add_new' => 'Add New Slider', 32 'add_new_item' => 'Add New Slider', 33 'edit_item' => 'Edit Slider', 34 ], 35 'public' => true, 36 'show_in_rest' => true, 37 'menu_icon' => 'dashicons-images-alt2', 38 'supports' => [ 'title', 'editor' ], 66 39 ] ); 67 } 68 69 /** 70 * 3. Admin Column: Shortcode 71 */ 72 add_filter( 'manage_rainbow_posts_columns', 'rainbow_slider_columns' ); 73 74 function rainbow_slider_columns( $columns ) { 40 }); 41 42 /*------------------------------------------------- 43 2. Admin Column: Shortcode 44 --------------------------------------------------*/ 45 add_filter( 'manage_rainbow_posts_columns', function( $columns ) { 75 46 $date = $columns['date']; 76 47 unset( $columns['date'] ); 77 $columns['shortcode'] = __( 'Shortcode', 'rainbow-slider' );48 $columns['shortcode'] = 'Shortcode'; 78 49 $columns['date'] = $date; 79 50 return $columns; 80 } 81 82 add_action( 'manage_rainbow_posts_custom_column', 'rainbow_slider_custom_column', 10, 2 ); 83 84 function rainbow_slider_custom_column( $column, $post_id ) { 51 }); 52 53 add_action( 'manage_rainbow_posts_custom_column', function( $column, $post_id ) { 85 54 if ( 'shortcode' === $column ) { 86 55 echo '<input type="text" 87 56 value="[rainbow_slider id=\'' . esc_attr( $post_id ) . '\']" 88 57 readonly 89 style="width:100%;max-width:260px;padding:6px;background:#f0f0f1;border:1px solid #ddd; border-radius:4px;"58 style="width:100%;max-width:260px;padding:6px;background:#f0f0f1;border:1px solid #ddd;" 90 59 onclick="this.select()">'; 91 60 } 92 } 93 94 /** 95 * 4. Elementor Support 96 */ 97 add_action( 'init', 'rainbow_slider_add_elementor_support', 99 ); 98 99 function rainbow_slider_add_elementor_support() { 61 }, 10, 2 ); 62 63 /*------------------------------------------------- 64 3. Elementor Support 65 --------------------------------------------------*/ 66 add_action( 'init', function () { 100 67 add_post_type_support( 'rainbow', 'elementor' ); 101 } 102 103 add_filter( 'elementor/utils/get_public_post_types', 'rainbow_slider_elementor_types' ); 104 105 function rainbow_slider_elementor_types( $types ) { 68 }, 99 ); 69 70 add_filter( 'elementor/utils/get_public_post_types', function ( $types ) { 106 71 $types[] = 'rainbow'; 107 72 return $types; 108 } 109 110 /** 111 * 5. Enqueue Assets & JS Logic 112 */ 113 add_action( 'wp_enqueue_scripts', 'rainbow_slider_enqueue_assets' ); 114 115 function rainbow_slider_enqueue_assets() { 116 117 // Load Swiper CSS 118 wp_enqueue_style( 'swiper', 'https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css', [], '11.0.0' ); 73 }); 74 75 /*------------------------------------------------- 76 4. Enqueue Swiper (CDN FIXED → LOCAL) 77 --------------------------------------------------*/ 78 add_action( 'wp_enqueue_scripts', function () { 79 80 // Swiper CSS (LOCAL) 81 wp_enqueue_style( 82 'swiper', 83 plugin_dir_url( __FILE__ ) . 'assets/swiper/swiper-bundle.min.css', 84 [], 85 '11.0.0' 86 ); 119 87 120 88 // Custom CSS 121 $custom_css = " 122 .rainbow-slider { 123 width: 100%; 124 position: relative; 125 overflow: hidden; 126 opacity: 0; 127 transition: opacity 0.3s ease; 128 min-height: 50px; 129 } 130 .rainbow-slider.rainbow-loaded { 131 opacity: 1; 132 } 133 .rainbow-slider .swiper-wrapper { 134 transition-property: transform, height; 135 box-sizing: border-box; 136 } 137 .rainbow-slider .swiper-slide { 138 height: auto; 139 width: 100%; 140 position: relative; 141 background-size: cover; 142 background-position: center; 143 display: block; 144 } 145 /* Fix for Elementor Sections & Containers */ 146 .rainbow-slider .swiper-slide > .elementor-section, 147 .rainbow-slider .swiper-slide > .elementor-top-section, 148 .rainbow-slider .swiper-slide > .e-con, 149 .rainbow-slider .swiper-slide > .e-parent, 150 .rainbow-slider .swiper-slide > .e-container { 151 width: 100% !important; 152 height: 100%; 153 } 154 "; 155 wp_add_inline_style( 'swiper', $custom_css ); 156 157 // Load Swiper JS 158 wp_enqueue_script( 'swiper', 'https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js', ['jquery'], '11.0.0', true ); 159 160 // JS Logic (Nowdoc Syntax) 161 $script = <<<'JS' 162 (function($){ 163 164 var initRainbowSlider = function() { 165 $('.rainbow-slider').each(function(){ 166 var slider = this; 167 if(slider.classList.contains('rainbow-loaded')) return; 168 169 var elementorInner = slider.querySelector('.elementor'); 170 if(!elementorInner) { 171 slider.classList.add('rainbow-loaded'); 172 return; 173 } 174 175 // Copy Classes 176 var originalClasses = elementorInner.className.split(' '); 177 originalClasses.forEach(function(cls){ 178 if(cls !== 'elementor') { 179 slider.classList.add(cls); 180 } 181 }); 182 183 // Get Items (Support: Sections, Flex Containers, Grid) 184 var sections = elementorInner.querySelectorAll( 185 ':scope > .elementor-section, :scope > .elementor-top-section, :scope > .e-con, :scope > .e-parent, :scope > .e-container' 186 ); 187 188 if(!sections.length) return; 189 190 // Build Wrapper 191 var wrapper = document.createElement('div'); 192 wrapper.className = 'swiper-wrapper'; 193 194 sections.forEach(function(section){ 195 var slide = document.createElement('div'); 196 slide.className = 'swiper-slide'; 197 slide.appendChild(section); 198 wrapper.appendChild(slide); 199 }); 200 201 // Clear & Rebuild 202 slider.innerHTML = ''; 203 slider.classList.add('elementor'); 204 slider.appendChild(wrapper); 205 206 // Controls 207 $(slider).append(` 208 <div class="swiper-pagination"></div> 209 <div class="swiper-button-next"></div> 210 <div class="swiper-button-prev"></div> 211 `); 212 89 wp_add_inline_style( 'swiper', " 90 .rainbow-slider{width:100%;position:relative;overflow:hidden;opacity:0;transition:opacity .3s ease;min-height:50px} 91 .rainbow-slider.rainbow-loaded{opacity:1} 92 .rainbow-slider .swiper-wrapper{transition-property:transform,height;box-sizing:border-box} 93 .rainbow-slider .swiper-slide{height:auto;width:100%;position:relative;display:block} 94 .rainbow-slider .swiper-slide>.elementor-section, 95 .rainbow-slider .swiper-slide>.elementor-top-section, 96 .rainbow-slider .swiper-slide>.e-con, 97 .rainbow-slider .swiper-slide>.e-parent, 98 .rainbow-slider .swiper-slide>.e-container, 99 .rainbow-slider .swiper-slide>.e-grid{width:100%!important;height:100%} 100 " ); 101 102 // Swiper JS (LOCAL) 103 wp_enqueue_script( 104 'swiper', 105 plugin_dir_url( __FILE__ ) . 'assets/swiper/swiper-bundle.min.js', 106 [ 'jquery' ], 107 '11.0.0', 108 true 109 ); 110 111 // Inline JS (UNCHANGED) 112 $js_code = <<<'JS' 113 (function($){ 114 var initRainbowSlider = function() { 115 $('.rainbow-slider').each(function(){ 116 var slider = this; 117 if(slider.classList.contains('rainbow-loaded')) return; 118 119 var elementorInner = slider.querySelector('.elementor'); 120 if(!elementorInner){ 213 121 slider.classList.add('rainbow-loaded'); 214 215 // Init Swiper 216 new Swiper(slider, { 217 slidesPerView: 1, 218 loop: true, 219 autoHeight: true, 220 observer: true, 221 observeParents: true, 222 effect: 'slide', 223 pagination: { 224 el: slider.querySelector('.swiper-pagination'), 225 clickable: true 226 }, 227 navigation: { 228 nextEl: slider.querySelector('.swiper-button-next'), 229 prevEl: slider.querySelector('.swiper-button-prev') 230 }, 231 autoplay: { 232 delay: 5000, 233 disableOnInteraction: false, 234 pauseOnMouseEnter: true 235 } 236 }); 237 238 // Trigger Elementor JS 239 if(window.elementorFrontend){ 240 try { elementorFrontend.init(); } catch(e){} 122 return; 123 } 124 125 var originalClasses = elementorInner.className.split(' '); 126 originalClasses.forEach(function(cls){ 127 if(cls !== 'elementor'){ 128 slider.classList.add(cls); 241 129 } 242 130 }); 243 }; 244 245 $(document).ready(initRainbowSlider); 246 247 $(window).on('elementor/frontend/init', function () { 248 elementorFrontend.hooks.addAction('frontend/element_ready/widget', function ($scope) { 249 if ( $scope.find('.rainbow-slider').length ) { 250 setTimeout(initRainbowSlider, 100); 131 132 var sections = elementorInner.querySelectorAll( 133 ':scope > .elementor-section,' + 134 ':scope > .elementor-top-section,' + 135 ':scope > .e-con,' + 136 ':scope > .e-parent,' + 137 ':scope > .e-container' 138 ); 139 if(!sections.length) return; 140 141 var wrapper = document.createElement('div'); 142 wrapper.className = 'swiper-wrapper'; 143 144 sections.forEach(function(section){ 145 var slide = document.createElement('div'); 146 slide.className = 'swiper-slide'; 147 slide.appendChild(section); 148 wrapper.appendChild(slide); 149 }); 150 151 slider.innerHTML = ''; 152 slider.classList.add('elementor'); 153 slider.appendChild(wrapper); 154 155 $(slider).append( 156 '<div class="swiper-pagination"></div>' + 157 '<div class="swiper-button-next"></div>' + 158 '<div class="swiper-button-prev"></div>' 159 ); 160 161 slider.classList.add('rainbow-loaded'); 162 163 new Swiper(slider,{ 164 slidesPerView:1, 165 loop:true, 166 autoHeight:true, 167 observer:true, 168 observeParents:true, 169 effect:'slide', 170 pagination:{el:slider.querySelector('.swiper-pagination'),clickable:true}, 171 navigation:{ 172 nextEl:slider.querySelector('.swiper-button-next'), 173 prevEl:slider.querySelector('.swiper-button-prev') 174 }, 175 autoplay:{ 176 delay:5000, 177 disableOnInteraction:false, 178 pauseOnMouseEnter:true 251 179 } 252 180 }); 181 182 if(window.elementorFrontend){ 183 try{ elementorFrontend.init(); }catch(e){} 184 } 253 185 }); 254 255 })(jQuery); 186 }; 187 188 $(document).ready(initRainbowSlider); 189 190 $(window).on('elementor/frontend/init',function(){ 191 elementorFrontend.hooks.addAction('frontend/element_ready/widget',function($scope){ 192 if($scope.find('.rainbow-slider').length){ 193 setTimeout(initRainbowSlider,100); 194 } 195 }); 196 }); 197 })(jQuery); 256 198 JS; 257 199 258 wp_add_inline_script( 'swiper', $script ); 259 } 260 261 /** 262 * 6. Shortcode Registration 263 */ 264 add_shortcode( 'rainbow_slider', 'rainbow_slider_shortcode' ); 265 200 wp_add_inline_script( 'swiper', $js_code ); 201 }); 202 203 /*------------------------------------------------- 204 5. Shortcode 205 --------------------------------------------------*/ 266 206 function rainbow_slider_shortcode( $atts ) { 267 207 $atts = shortcode_atts([ 'id' => 0 ], $atts ); … … 270 210 if ( ! $post_id || ! class_exists( '\\Elementor\\Plugin' ) ) return ''; 271 211 272 // Verify Post Type273 if ( get_post_type( $post_id ) !== 'rainbow' ) return '';274 275 212 $content = \Elementor\Plugin::instance() 276 213 ->frontend 277 214 ->get_builder_content_for_display( $post_id ); 278 215 279 return '<div class="swiper rainbow-slider" id="rainbow-slider-' . esc_attr( $post_id ) . '">' 280 . $content .216 return '<div class="swiper rainbow-slider" id="rainbow-slider-' . esc_attr( $post_id ) . '">' . 217 $content . 281 218 '</div>'; 282 219 } 220 add_shortcode( 'rainbow_slider', 'rainbow_slider_shortcode' );
Note: See TracChangeset
for help on using the changeset viewer.