image-box.php (16762B)
1 <?php 2 namespace Elementor; 3 4 if ( ! defined( 'ABSPATH' ) ) { 5 exit; // Exit if accessed directly. 6 } 7 8 use Elementor\Core\Kits\Documents\Tabs\Global_Colors; 9 use Elementor\Core\Kits\Documents\Tabs\Global_Typography; 10 11 /** 12 * Elementor image box widget. 13 * 14 * Elementor widget that displays an image, a headline and a text. 15 * 16 * @since 1.0.0 17 */ 18 class Widget_Image_Box extends Widget_Base { 19 20 /** 21 * Get widget name. 22 * 23 * Retrieve image box widget name. 24 * 25 * @since 1.0.0 26 * @access public 27 * 28 * @return string Widget name. 29 */ 30 public function get_name() { 31 return 'image-box'; 32 } 33 34 /** 35 * Get widget title. 36 * 37 * Retrieve image box widget title. 38 * 39 * @since 1.0.0 40 * @access public 41 * 42 * @return string Widget title. 43 */ 44 public function get_title() { 45 return esc_html__( 'Image Box', 'elementor' ); 46 } 47 48 /** 49 * Get widget icon. 50 * 51 * Retrieve image box widget icon. 52 * 53 * @since 1.0.0 54 * @access public 55 * 56 * @return string Widget icon. 57 */ 58 public function get_icon() { 59 return 'eicon-image-box'; 60 } 61 62 /** 63 * Get widget keywords. 64 * 65 * Retrieve the list of keywords the widget belongs to. 66 * 67 * @since 2.1.0 68 * @access public 69 * 70 * @return array Widget keywords. 71 */ 72 public function get_keywords() { 73 return [ 'image', 'photo', 'visual', 'box' ]; 74 } 75 76 /** 77 * Register image box widget controls. 78 * 79 * Adds different input fields to allow the user to change and customize the widget settings. 80 * 81 * @since 3.1.0 82 * @access protected 83 */ 84 protected function register_controls() { 85 $this->start_controls_section( 86 'section_image', 87 [ 88 'label' => esc_html__( 'Image Box', 'elementor' ), 89 ] 90 ); 91 92 $this->add_control( 93 'image', 94 [ 95 'label' => esc_html__( 'Choose Image', 'elementor' ), 96 'type' => Controls_Manager::MEDIA, 97 'dynamic' => [ 98 'active' => true, 99 ], 100 'default' => [ 101 'url' => Utils::get_placeholder_image_src(), 102 ], 103 ] 104 ); 105 106 $this->add_group_control( 107 Group_Control_Image_Size::get_type(), 108 [ 109 'name' => 'thumbnail', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `thumbnail_size` and `thumbnail_custom_dimension`. 110 'default' => 'full', 111 'separator' => 'none', 112 ] 113 ); 114 115 $this->add_control( 116 'title_text', 117 [ 118 'label' => esc_html__( 'Title & Description', 'elementor' ), 119 'type' => Controls_Manager::TEXT, 120 'dynamic' => [ 121 'active' => true, 122 ], 123 'default' => esc_html__( 'This is the heading', 'elementor' ), 124 'placeholder' => esc_html__( 'Enter your title', 'elementor' ), 125 'label_block' => true, 126 ] 127 ); 128 129 $this->add_control( 130 'description_text', 131 [ 132 'label' => esc_html__( 'Content', 'elementor' ), 133 'type' => Controls_Manager::TEXTAREA, 134 'dynamic' => [ 135 'active' => true, 136 ], 137 'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ), 138 'placeholder' => esc_html__( 'Enter your description', 'elementor' ), 139 'separator' => 'none', 140 'rows' => 10, 141 'show_label' => false, 142 ] 143 ); 144 145 $this->add_control( 146 'link', 147 [ 148 'label' => esc_html__( 'Link', 'elementor' ), 149 'type' => Controls_Manager::URL, 150 'dynamic' => [ 151 'active' => true, 152 ], 153 'placeholder' => esc_html__( 'https://your-link.com', 'elementor' ), 154 'separator' => 'before', 155 ] 156 ); 157 158 $this->add_control( 159 'position', 160 [ 161 'label' => esc_html__( 'Image Position', 'elementor' ), 162 'type' => Controls_Manager::CHOOSE, 163 'default' => 'top', 164 'options' => [ 165 'left' => [ 166 'title' => esc_html__( 'Left', 'elementor' ), 167 'icon' => 'eicon-h-align-left', 168 ], 169 'top' => [ 170 'title' => esc_html__( 'Top', 'elementor' ), 171 'icon' => 'eicon-v-align-top', 172 ], 173 'right' => [ 174 'title' => esc_html__( 'Right', 'elementor' ), 175 'icon' => 'eicon-h-align-right', 176 ], 177 ], 178 'prefix_class' => 'elementor-position-', 179 'toggle' => false, 180 ] 181 ); 182 183 $this->add_control( 184 'title_size', 185 [ 186 'label' => esc_html__( 'Title HTML Tag', 'elementor' ), 187 'type' => Controls_Manager::SELECT, 188 'options' => [ 189 'h1' => 'H1', 190 'h2' => 'H2', 191 'h3' => 'H3', 192 'h4' => 'H4', 193 'h5' => 'H5', 194 'h6' => 'H6', 195 'div' => 'div', 196 'span' => 'span', 197 'p' => 'p', 198 ], 199 'default' => 'h3', 200 ] 201 ); 202 203 $this->add_control( 204 'view', 205 [ 206 'label' => esc_html__( 'View', 'elementor' ), 207 'type' => Controls_Manager::HIDDEN, 208 'default' => 'traditional', 209 ] 210 ); 211 212 $this->end_controls_section(); 213 214 $this->start_controls_section( 215 'section_style_image', 216 [ 217 'label' => esc_html__( 'Image', 'elementor' ), 218 'tab' => Controls_Manager::TAB_STYLE, 219 ] 220 ); 221 222 $this->add_responsive_control( 223 'image_space', 224 [ 225 'label' => esc_html__( 'Spacing', 'elementor' ), 226 'type' => Controls_Manager::SLIDER, 227 'default' => [ 228 'size' => 15, 229 ], 230 'range' => [ 231 'px' => [ 232 'min' => 0, 233 'max' => 100, 234 ], 235 ], 236 'selectors' => [ 237 '{{WRAPPER}}.elementor-position-right .elementor-image-box-img' => 'margin-left: {{SIZE}}{{UNIT}};', 238 '{{WRAPPER}}.elementor-position-left .elementor-image-box-img' => 'margin-right: {{SIZE}}{{UNIT}};', 239 '{{WRAPPER}}.elementor-position-top .elementor-image-box-img' => 'margin-bottom: {{SIZE}}{{UNIT}};', 240 '(mobile){{WRAPPER}} .elementor-image-box-img' => 'margin-bottom: {{SIZE}}{{UNIT}};', 241 ], 242 ] 243 ); 244 245 $this->add_responsive_control( 246 'image_size', 247 [ 248 'label' => esc_html__( 'Width', 'elementor' ) . ' (%)', 249 'type' => Controls_Manager::SLIDER, 250 'default' => [ 251 'size' => 30, 252 'unit' => '%', 253 ], 254 'tablet_default' => [ 255 'unit' => '%', 256 ], 257 'mobile_default' => [ 258 'unit' => '%', 259 ], 260 'size_units' => [ '%' ], 261 'range' => [ 262 '%' => [ 263 'min' => 5, 264 'max' => 100, 265 ], 266 ], 267 'selectors' => [ 268 '{{WRAPPER}} .elementor-image-box-wrapper .elementor-image-box-img' => 'width: {{SIZE}}{{UNIT}};', 269 ], 270 ] 271 ); 272 273 $this->add_responsive_control( 274 'image_border_radius', 275 [ 276 'label' => esc_html__( 'Border Radius', 'elementor' ), 277 'type' => Controls_Manager::SLIDER, 278 'size_units' => [ 'px', '%' ], 279 'selectors' => [ 280 '{{WRAPPER}} .elementor-image-box-wrapper img' => 'border-radius: {{SIZE}}{{UNIT}};', 281 ], 282 ] 283 ); 284 285 $this->add_control( 286 'hover_animation', 287 [ 288 'label' => esc_html__( 'Hover Animation', 'elementor' ), 289 'type' => Controls_Manager::HOVER_ANIMATION, 290 ] 291 ); 292 293 $this->start_controls_tabs( 'image_effects' ); 294 295 $this->start_controls_tab( 'normal', 296 [ 297 'label' => esc_html__( 'Normal', 'elementor' ), 298 ] 299 ); 300 301 $this->add_group_control( 302 Group_Control_Css_Filter::get_type(), 303 [ 304 'name' => 'css_filters', 305 'selector' => '{{WRAPPER}} .elementor-image-box-img img', 306 ] 307 ); 308 309 $this->add_control( 310 'image_opacity', 311 [ 312 'label' => esc_html__( 'Opacity', 'elementor' ), 313 'type' => Controls_Manager::SLIDER, 314 'range' => [ 315 'px' => [ 316 'max' => 1, 317 'min' => 0.10, 318 'step' => 0.01, 319 ], 320 ], 321 'selectors' => [ 322 '{{WRAPPER}} .elementor-image-box-img img' => 'opacity: {{SIZE}};', 323 ], 324 ] 325 ); 326 327 $this->add_control( 328 'background_hover_transition', 329 [ 330 'label' => esc_html__( 'Transition Duration', 'elementor' ), 331 'type' => Controls_Manager::SLIDER, 332 'default' => [ 333 'size' => 0.3, 334 ], 335 'range' => [ 336 'px' => [ 337 'max' => 3, 338 'step' => 0.1, 339 ], 340 ], 341 'selectors' => [ 342 '{{WRAPPER}} .elementor-image-box-img img' => 'transition-duration: {{SIZE}}s', 343 ], 344 ] 345 ); 346 347 $this->end_controls_tab(); 348 349 $this->start_controls_tab( 'hover', 350 [ 351 'label' => esc_html__( 'Hover', 'elementor' ), 352 ] 353 ); 354 355 $this->add_group_control( 356 Group_Control_Css_Filter::get_type(), 357 [ 358 'name' => 'css_filters_hover', 359 'selector' => '{{WRAPPER}}:hover .elementor-image-box-img img', 360 ] 361 ); 362 363 $this->add_control( 364 'image_opacity_hover', 365 [ 366 'label' => esc_html__( 'Opacity', 'elementor' ), 367 'type' => Controls_Manager::SLIDER, 368 'range' => [ 369 'px' => [ 370 'max' => 1, 371 'min' => 0.10, 372 'step' => 0.01, 373 ], 374 ], 375 'selectors' => [ 376 '{{WRAPPER}}:hover .elementor-image-box-img img' => 'opacity: {{SIZE}};', 377 ], 378 ] 379 ); 380 381 $this->end_controls_tab(); 382 383 $this->end_controls_tabs(); 384 385 $this->end_controls_section(); 386 387 $this->start_controls_section( 388 'section_style_content', 389 [ 390 'label' => esc_html__( 'Content', 'elementor' ), 391 'tab' => Controls_Manager::TAB_STYLE, 392 ] 393 ); 394 395 $this->add_responsive_control( 396 'text_align', 397 [ 398 'label' => esc_html__( 'Alignment', 'elementor' ), 399 'type' => Controls_Manager::CHOOSE, 400 'options' => [ 401 'left' => [ 402 'title' => esc_html__( 'Left', 'elementor' ), 403 'icon' => 'eicon-text-align-left', 404 ], 405 'center' => [ 406 'title' => esc_html__( 'Center', 'elementor' ), 407 'icon' => 'eicon-text-align-center', 408 ], 409 'right' => [ 410 'title' => esc_html__( 'Right', 'elementor' ), 411 'icon' => 'eicon-text-align-right', 412 ], 413 'justify' => [ 414 'title' => esc_html__( 'Justified', 'elementor' ), 415 'icon' => 'eicon-text-align-justify', 416 ], 417 ], 418 'selectors' => [ 419 '{{WRAPPER}} .elementor-image-box-wrapper' => 'text-align: {{VALUE}};', 420 ], 421 ] 422 ); 423 424 $this->add_control( 425 'content_vertical_alignment', 426 [ 427 'label' => esc_html__( 'Vertical Alignment', 'elementor' ), 428 'type' => Controls_Manager::SELECT, 429 'options' => [ 430 'top' => esc_html__( 'Top', 'elementor' ), 431 'middle' => esc_html__( 'Middle', 'elementor' ), 432 'bottom' => esc_html__( 'Bottom', 'elementor' ), 433 ], 434 'default' => 'top', 435 'prefix_class' => 'elementor-vertical-align-', 436 ] 437 ); 438 439 $this->add_control( 440 'heading_title', 441 [ 442 'label' => esc_html__( 'Title', 'elementor' ), 443 'type' => Controls_Manager::HEADING, 444 'separator' => 'before', 445 ] 446 ); 447 448 $this->add_responsive_control( 449 'title_bottom_space', 450 [ 451 'label' => esc_html__( 'Spacing', 'elementor' ), 452 'type' => Controls_Manager::SLIDER, 453 'range' => [ 454 'px' => [ 455 'min' => 0, 456 'max' => 100, 457 ], 458 ], 459 'selectors' => [ 460 '{{WRAPPER}} .elementor-image-box-title' => 'margin-bottom: {{SIZE}}{{UNIT}};', 461 ], 462 ] 463 ); 464 465 $this->add_control( 466 'title_color', 467 [ 468 'label' => esc_html__( 'Color', 'elementor' ), 469 'type' => Controls_Manager::COLOR, 470 'default' => '', 471 'selectors' => [ 472 '{{WRAPPER}} .elementor-image-box-title' => 'color: {{VALUE}};', 473 ], 474 'global' => [ 475 'default' => Global_Colors::COLOR_PRIMARY, 476 ], 477 ] 478 ); 479 480 $this->add_group_control( 481 Group_Control_Typography::get_type(), 482 [ 483 'name' => 'title_typography', 484 'selector' => '{{WRAPPER}} .elementor-image-box-title', 485 'global' => [ 486 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, 487 ], 488 ] 489 ); 490 491 $this->add_group_control( 492 Group_Control_Text_Shadow::get_type(), 493 [ 494 'name' => 'title_shadow', 495 'selector' => '{{WRAPPER}} .elementor-image-box-title', 496 ] 497 ); 498 499 $this->add_control( 500 'heading_description', 501 [ 502 'label' => esc_html__( 'Description', 'elementor' ), 503 'type' => Controls_Manager::HEADING, 504 'separator' => 'before', 505 ] 506 ); 507 508 $this->add_control( 509 'description_color', 510 [ 511 'label' => esc_html__( 'Color', 'elementor' ), 512 'type' => Controls_Manager::COLOR, 513 'default' => '', 514 'selectors' => [ 515 '{{WRAPPER}} .elementor-image-box-description' => 'color: {{VALUE}};', 516 ], 517 'global' => [ 518 'default' => Global_Colors::COLOR_TEXT, 519 ], 520 ] 521 ); 522 523 $this->add_group_control( 524 Group_Control_Typography::get_type(), 525 [ 526 'name' => 'description_typography', 527 'selector' => '{{WRAPPER}} .elementor-image-box-description', 528 'global' => [ 529 'default' => Global_Typography::TYPOGRAPHY_TEXT, 530 ], 531 ] 532 ); 533 534 $this->add_group_control( 535 Group_Control_Text_Shadow::get_type(), 536 [ 537 'name' => 'description_shadow', 538 'selector' => '{{WRAPPER}} .elementor-image-box-description', 539 ] 540 ); 541 542 $this->end_controls_section(); 543 } 544 545 /** 546 * Render image box widget output on the frontend. 547 * 548 * Written in PHP and used to generate the final HTML. 549 * 550 * @since 1.0.0 551 * @access protected 552 */ 553 protected function render() { 554 $settings = $this->get_settings_for_display(); 555 556 $has_content = ! Utils::is_empty( $settings['title_text'] ) || ! Utils::is_empty( $settings['description_text'] ); 557 558 $html = '<div class="elementor-image-box-wrapper">'; 559 560 if ( ! empty( $settings['link']['url'] ) ) { 561 $this->add_link_attributes( 'link', $settings['link'] ); 562 } 563 564 if ( ! empty( $settings['image']['url'] ) ) { 565 $this->add_render_attribute( 'image', 'src', $settings['image']['url'] ); 566 $this->add_render_attribute( 'image', 'alt', Control_Media::get_image_alt( $settings['image'] ) ); 567 $this->add_render_attribute( 'image', 'title', Control_Media::get_image_title( $settings['image'] ) ); 568 569 if ( $settings['hover_animation'] ) { 570 $this->add_render_attribute( 'image', 'class', 'elementor-animation-' . $settings['hover_animation'] ); 571 } 572 573 $image_html = wp_kses_post( Group_Control_Image_Size::get_attachment_image_html( $settings, 'thumbnail', 'image' ) ); 574 575 if ( ! empty( $settings['link']['url'] ) ) { 576 $image_html = '<a ' . $this->get_render_attribute_string( 'link' ) . '>' . $image_html . '</a>'; 577 } 578 579 $html .= '<figure class="elementor-image-box-img">' . $image_html . '</figure>'; 580 } 581 582 if ( $has_content ) { 583 $html .= '<div class="elementor-image-box-content">'; 584 585 if ( ! Utils::is_empty( $settings['title_text'] ) ) { 586 $this->add_render_attribute( 'title_text', 'class', 'elementor-image-box-title' ); 587 588 $this->add_inline_editing_attributes( 'title_text', 'none' ); 589 590 $title_html = $settings['title_text']; 591 592 if ( ! empty( $settings['link']['url'] ) ) { 593 $title_html = '<a ' . $this->get_render_attribute_string( 'link' ) . '>' . $title_html . '</a>'; 594 } 595 596 $html .= sprintf( '<%1$s %2$s>%3$s</%1$s>', Utils::validate_html_tag( $settings['title_size'] ), $this->get_render_attribute_string( 'title_text' ), $title_html ); 597 } 598 599 if ( ! Utils::is_empty( $settings['description_text'] ) ) { 600 $this->add_render_attribute( 'description_text', 'class', 'elementor-image-box-description' ); 601 602 $this->add_inline_editing_attributes( 'description_text' ); 603 604 $html .= sprintf( '<p %1$s>%2$s</p>', $this->get_render_attribute_string( 'description_text' ), $settings['description_text'] ); 605 } 606 607 $html .= '</div>'; 608 } 609 610 $html .= '</div>'; 611 612 Utils::print_unescaped_internal_string( $html ); 613 } 614 615 /** 616 * Render image box widget output in the editor. 617 * 618 * Written as a Backbone JavaScript template and used to generate the live preview. 619 * 620 * @since 2.9.0 621 * @access protected 622 */ 623 protected function content_template() { 624 ?> 625 <# 626 var html = '<div class="elementor-image-box-wrapper">'; 627 628 if ( settings.image.url ) { 629 var image = { 630 id: settings.image.id, 631 url: settings.image.url, 632 size: settings.thumbnail_size, 633 dimension: settings.thumbnail_custom_dimension, 634 model: view.getEditModel() 635 }; 636 637 var image_url = elementor.imagesManager.getImageUrl( image ); 638 639 var imageHtml = '<img src="' + image_url + '" class="elementor-animation-' + settings.hover_animation + '" />'; 640 641 if ( settings.link.url ) { 642 imageHtml = '<a href="' + settings.link.url + '">' + imageHtml + '</a>'; 643 } 644 645 html += '<figure class="elementor-image-box-img">' + imageHtml + '</figure>'; 646 } 647 648 var hasContent = !! ( settings.title_text || settings.description_text ); 649 650 if ( hasContent ) { 651 html += '<div class="elementor-image-box-content">'; 652 653 if ( settings.title_text ) { 654 var title_html = settings.title_text, 655 titleSizeTag = elementor.helpers.validateHTMLTag( settings.title_size ); 656 657 if ( settings.link.url ) { 658 title_html = '<a href="' + settings.link.url + '">' + title_html + '</a>'; 659 } 660 661 view.addRenderAttribute( 'title_text', 'class', 'elementor-image-box-title' ); 662 663 view.addInlineEditingAttributes( 'title_text', 'none' ); 664 665 html += '<' + titleSizeTag + ' ' + view.getRenderAttributeString( 'title_text' ) + '>' + title_html + '</' + titleSizeTag + '>'; 666 } 667 668 if ( settings.description_text ) { 669 view.addRenderAttribute( 'description_text', 'class', 'elementor-image-box-description' ); 670 671 view.addInlineEditingAttributes( 'description_text' ); 672 673 html += '<p ' + view.getRenderAttributeString( 'description_text' ) + '>' + settings.description_text + '</p>'; 674 } 675 676 html += '</div>'; 677 } 678 679 html += '</div>'; 680 681 print( html ); 682 #> 683 <?php 684 } 685 }