parent = $widget; $this->register_design_controls(); } public function register_controls( Widget_Base $widget ) { $this->parent = $widget; $this->register_columns_controls(); $this->register_post_count_control(); $this->register_thumbnail_controls(); $this->register_title_controls(); $this->register_excerpt_controls(); $this->register_meta_data_controls(); $this->register_read_more_controls(); $this->register_link_controls(); } public function register_design_controls() { $this->register_design_layout_controls(); $this->register_design_image_controls(); $this->register_design_content_controls(); } protected function register_thumbnail_controls() { $this->add_control( 'thumbnail', [ 'label' => esc_html__( 'Image Position', 'elementor-pro' ), 'type' => Controls_Manager::SELECT, 'default' => 'top', 'options' => [ 'top' => esc_html__( 'Top', 'elementor-pro' ), 'left' => esc_html__( 'Left', 'elementor-pro' ), 'right' => esc_html__( 'Right', 'elementor-pro' ), 'none' => esc_html__( 'None', 'elementor-pro' ), ], 'prefix_class' => 'elementor-posts--thumbnail-', ] ); $this->add_control( 'masonry', [ 'label' => esc_html__( 'Masonry', 'elementor-pro' ), 'type' => Controls_Manager::SWITCHER, 'label_off' => esc_html__( 'Off', 'elementor-pro' ), 'label_on' => esc_html__( 'On', 'elementor-pro' ), 'condition' => [ $this->get_control_id( 'columns!' ) => '1', $this->get_control_id( 'thumbnail' ) => 'top', ], 'render_type' => 'ui', 'frontend_available' => true, ] ); $this->add_group_control( Group_Control_Image_Size::get_type(), [ 'name' => 'thumbnail_size', 'default' => 'medium', 'exclude' => [ 'custom' ], 'condition' => [ $this->get_control_id( 'thumbnail!' ) => 'none', ], 'prefix_class' => 'elementor-posts--thumbnail-size-', ] ); $this->add_responsive_control( 'item_ratio', [ 'label' => esc_html__( 'Image Ratio', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'default' => [ 'size' => 0.66, ], 'tablet_default' => [ 'size' => '', ], 'mobile_default' => [ 'size' => 0.5, ], 'range' => [ 'px' => [ 'min' => 0.1, 'max' => 2, 'step' => 0.01, ], ], 'selectors' => [ '{{WRAPPER}} .elementor-posts-container .elementor-post__thumbnail' => 'padding-bottom: calc( {{SIZE}} * 100% );', '{{WRAPPER}}:after' => 'content: "{{SIZE}}";', ], 'condition' => [ $this->get_control_id( 'thumbnail!' ) => 'none', $this->get_control_id( 'masonry' ) => '', ], ] ); $this->add_responsive_control( 'image_width', [ 'label' => esc_html__( 'Image Width', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], 'range' => [ '%' => [ 'min' => 10, 'max' => 100, ], 'px' => [ 'min' => 10, 'max' => 600, ], 'em' => [ 'min' => 1, 'max' => 60, ], 'rem' => [ 'min' => 1, 'max' => 60, ], ], 'default' => [ 'size' => 100, 'unit' => '%', ], 'tablet_default' => [ 'size' => '', 'unit' => '%', ], 'mobile_default' => [ 'size' => 100, 'unit' => '%', ], 'selectors' => [ '{{WRAPPER}} .elementor-post__thumbnail__link' => 'width: {{SIZE}}{{UNIT}};', ], 'condition' => [ $this->get_control_id( 'thumbnail!' ) => 'none', ], ] ); } protected function register_columns_controls() { $this->add_responsive_control( 'columns', [ 'label' => esc_html__( 'Columns', 'elementor-pro' ), 'type' => Controls_Manager::SELECT, 'default' => '3', 'tablet_default' => '2', 'mobile_default' => '1', 'options' => [ '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', ], 'prefix_class' => 'elementor-grid%s-', 'frontend_available' => true, ] ); } protected function register_post_count_control() { $this->add_control( 'posts_per_page', [ 'label' => esc_html__( 'Posts Per Page', 'elementor-pro' ), 'type' => Controls_Manager::NUMBER, 'default' => 6, ] ); } protected function register_title_controls() { $this->add_control( 'show_title', [ 'label' => esc_html__( 'Title', 'elementor-pro' ), 'type' => Controls_Manager::SWITCHER, 'label_on' => esc_html__( 'Show', 'elementor-pro' ), 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), 'default' => 'yes', 'separator' => 'before', ] ); $this->add_control( 'title_tag', [ 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), 'type' => Controls_Manager::SELECT, 'options' => [ 'h1' => 'H1', 'h2' => 'H2', 'h3' => 'H3', 'h4' => 'H4', 'h5' => 'H5', 'h6' => 'H6', 'div' => 'div', 'span' => 'span', 'p' => 'p', ], 'default' => 'h3', 'condition' => [ $this->get_control_id( 'show_title' ) => 'yes', ], ] ); } protected function register_excerpt_controls() { $this->add_control( 'show_excerpt', [ 'label' => esc_html__( 'Excerpt', 'elementor-pro' ), 'type' => Controls_Manager::SWITCHER, 'label_on' => esc_html__( 'Show', 'elementor-pro' ), 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), 'default' => 'yes', ] ); $this->add_control( 'excerpt_length', [ 'label' => esc_html__( 'Excerpt Length', 'elementor-pro' ), 'type' => Controls_Manager::NUMBER, /** This filter is documented in wp-includes/formatting.php */ 'default' => apply_filters( 'excerpt_length', 25 ), 'condition' => [ $this->get_control_id( 'show_excerpt' ) => 'yes', ], ] ); $this->add_control( 'apply_to_custom_excerpt', [ 'label' => esc_html__( 'Apply to custom Excerpt', 'elementor-pro' ), 'type' => Controls_Manager::SWITCHER, 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), 'label_off' => esc_html__( 'No', 'elementor-pro' ), 'default' => 'no', 'condition' => [ $this->get_control_id( 'show_excerpt' ) => 'yes', ], ] ); } protected function register_read_more_controls() { $this->add_control( 'show_read_more', [ 'label' => esc_html__( 'Read More', 'elementor-pro' ), 'type' => Controls_Manager::SWITCHER, 'label_on' => esc_html__( 'Show', 'elementor-pro' ), 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), 'default' => 'yes', 'separator' => 'before', ] ); $this->add_control( 'read_more_text', [ 'label' => esc_html__( 'Read More Text', 'elementor-pro' ), 'type' => Controls_Manager::TEXT, 'dynamic' => [ 'active' => true, ], 'ai' => [ 'active' => false, ], 'default' => esc_html__( 'Read More ยป', 'elementor-pro' ), 'condition' => [ $this->get_control_id( 'show_read_more' ) => 'yes', ], ] ); $this->add_control( 'read_more_alignment', [ 'label' => esc_html__( 'Automatically align buttons', 'elementor-pro' ), 'type' => Controls_Manager::SWITCHER, 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), 'label_off' => esc_html__( 'No', 'elementor-pro' ), 'default' => '', 'render_type' => 'template', 'selectors' => [ // --item-display is used for the styling of both elementor-post__card and elementor-post__text '{{WRAPPER}}' => '--item-display: flex; --read-more-alignment: 1;', ], 'condition' => [ $this->get_control_id( 'masonry!' ) => 'yes', $this->get_control_id( 'show_read_more' ) => 'yes', ], ] ); } protected function register_link_controls() { $this->add_control( 'open_new_tab', [ 'label' => esc_html__( 'Open in new window', 'elementor-pro' ), 'type' => Controls_Manager::SWITCHER, 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), 'label_off' => esc_html__( 'No', 'elementor-pro' ), 'default' => 'no', 'render_type' => 'none', ] ); } protected function get_optional_link_attributes_html() { $settings = $this->parent->get_settings(); $new_tab_setting_key = $this->get_control_id( 'open_new_tab' ); $optional_attributes_html = 'yes' === $settings[ $new_tab_setting_key ] ? 'target="_blank"' : ''; return $optional_attributes_html; } protected function register_meta_data_controls() { $this->add_control( 'meta_data', [ 'label' => esc_html__( 'Meta Data', 'elementor-pro' ), 'label_block' => true, 'type' => Controls_Manager::SELECT2, 'default' => [ 'date', 'comments' ], 'multiple' => true, 'options' => [ 'author' => esc_html__( 'Author', 'elementor-pro' ), 'date' => esc_html__( 'Date', 'elementor-pro' ), 'time' => esc_html__( 'Time', 'elementor-pro' ), 'comments' => esc_html__( 'Comments', 'elementor-pro' ), 'modified' => esc_html__( 'Date Modified', 'elementor-pro' ), ], 'separator' => 'before', ] ); $this->add_control( 'meta_separator', [ 'label' => esc_html__( 'Separator Between', 'elementor-pro' ), 'type' => Controls_Manager::TEXT, 'default' => '///', 'ai' => [ 'active' => false, ], 'selectors' => [ '{{WRAPPER}} .elementor-post__meta-data span + span:before' => 'content: "{{VALUE}}"', ], 'condition' => [ $this->get_control_id( 'meta_data!' ) => [], ], 'dynamic' => [ 'active' => true, ], ] ); } /** * Style Tab */ protected function register_design_layout_controls() { $this->start_controls_section( 'section_design_layout', [ 'label' => esc_html__( 'Layout', 'elementor-pro' ), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_responsive_control( 'column_gap', [ 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'custom' ], 'default' => [ 'size' => 30, ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'max' => 10, ], 'rem' => [ 'max' => 10, ], ], 'selectors' => [ '{{WRAPPER}}' => '--grid-column-gap: {{SIZE}}{{UNIT}}', ], ] ); $this->add_responsive_control( 'row_gap', [ 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'custom' ], 'default' => [ 'size' => 35, ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'max' => 10, ], 'rem' => [ 'max' => 10, ], ], 'frontend_available' => true, 'selectors' => [ '{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}', ], ] ); $this->add_control( 'alignment', [ 'label' => esc_html__( 'Alignment', 'elementor-pro' ), 'type' => Controls_Manager::CHOOSE, 'options' => [ 'left' => [ 'title' => esc_html__( 'Left', 'elementor-pro' ), 'icon' => 'eicon-text-align-left', ], 'center' => [ 'title' => esc_html__( 'Center', 'elementor-pro' ), 'icon' => 'eicon-text-align-center', ], 'right' => [ 'title' => esc_html__( 'Right', 'elementor-pro' ), 'icon' => 'eicon-text-align-right', ], ], 'prefix_class' => 'elementor-posts--align-', ] ); $this->end_controls_section(); } protected function register_design_image_controls() { $this->start_controls_section( 'section_design_image', [ 'label' => esc_html__( 'Image', 'elementor-pro' ), 'tab' => Controls_Manager::TAB_STYLE, 'condition' => [ $this->get_control_id( 'thumbnail!' ) => 'none', ], ] ); $this->add_responsive_control( 'img_border_radius', [ 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], 'selectors' => [ '{{WRAPPER}} .elementor-post__thumbnail' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], 'condition' => [ $this->get_control_id( 'thumbnail!' ) => 'none', ], ] ); $this->add_responsive_control( 'image_spacing', [ 'label' => esc_html__( 'Spacing', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'custom' ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'max' => 10, ], 'rem' => [ 'max' => 10, ], ], 'selectors' => [ '{{WRAPPER}}.elementor-posts--thumbnail-left .elementor-post__thumbnail__link' => 'margin-right: {{SIZE}}{{UNIT}}', '{{WRAPPER}}.elementor-posts--thumbnail-right .elementor-post__thumbnail__link' => 'margin-left: {{SIZE}}{{UNIT}}', '{{WRAPPER}}.elementor-posts--thumbnail-top .elementor-post__thumbnail__link' => 'margin-bottom: {{SIZE}}{{UNIT}}', ], 'default' => [ 'size' => 20, ], 'condition' => [ $this->get_control_id( 'thumbnail!' ) => 'none', ], ] ); $this->start_controls_tabs( 'thumbnail_effects_tabs' ); $this->start_controls_tab( 'normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ), ] ); $this->add_group_control( Group_Control_Css_Filter::get_type(), [ 'name' => 'thumbnail_filters', 'selector' => '{{WRAPPER}} .elementor-post__thumbnail img', ] ); $this->end_controls_tab(); $this->start_controls_tab( 'hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ), ] ); $this->add_group_control( Group_Control_Css_Filter::get_type(), [ 'name' => 'thumbnail_hover_filters', 'selector' => '{{WRAPPER}} .elementor-post:hover .elementor-post__thumbnail img', ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->end_controls_section(); } protected function register_design_content_controls() { $this->start_controls_section( 'section_design_content', [ 'label' => esc_html__( 'Content', 'elementor-pro' ), 'tab' => Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'heading_title_style', [ 'label' => esc_html__( 'Title', 'elementor-pro' ), 'type' => Controls_Manager::HEADING, 'condition' => [ $this->get_control_id( 'show_title' ) => 'yes', ], ] ); $this->add_control( 'title_color', [ 'label' => esc_html__( 'Color', 'elementor-pro' ), 'type' => Controls_Manager::COLOR, 'global' => [ 'default' => Global_Colors::COLOR_SECONDARY, ], 'selectors' => [ '{{WRAPPER}} .elementor-post__title, {{WRAPPER}} .elementor-post__title a' => 'color: {{VALUE}};', ], 'condition' => [ $this->get_control_id( 'show_title' ) => 'yes', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'title_typography', 'global' => [ 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, ], 'selector' => '{{WRAPPER}} .elementor-post__title, {{WRAPPER}} .elementor-post__title a', 'condition' => [ $this->get_control_id( 'show_title' ) => 'yes', ], ] ); $this->add_group_control( Group_Control_Text_Stroke::get_type(), [ 'name' => 'text_stroke', 'selector' => '{{WRAPPER}} .elementor-post__title', ] ); $this->add_responsive_control( 'title_spacing', [ 'label' => esc_html__( 'Spacing', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'custom' ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'max' => 10, ], 'rem' => [ 'max' => 10, ], ], 'selectors' => [ '{{WRAPPER}} .elementor-post__title' => 'margin-bottom: {{SIZE}}{{UNIT}};', ], 'condition' => [ $this->get_control_id( 'show_title' ) => 'yes', ], ] ); $this->add_control( 'heading_meta_style', [ 'label' => esc_html__( 'Meta', 'elementor-pro' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', 'condition' => [ $this->get_control_id( 'meta_data!' ) => [], ], ] ); $this->add_control( 'meta_color', [ 'label' => esc_html__( 'Color', 'elementor-pro' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .elementor-post__meta-data' => 'color: {{VALUE}};', ], 'condition' => [ $this->get_control_id( 'meta_data!' ) => [], ], ] ); $this->add_control( 'meta_separator_color', [ 'label' => esc_html__( 'Separator Color', 'elementor-pro' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .elementor-post__meta-data span:before' => 'color: {{VALUE}};', ], 'condition' => [ $this->get_control_id( 'meta_data!' ) => [], ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'meta_typography', 'global' => [ 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, ], 'selector' => '{{WRAPPER}} .elementor-post__meta-data', 'condition' => [ $this->get_control_id( 'meta_data!' ) => [], ], ] ); $this->add_responsive_control( 'meta_spacing', [ 'label' => esc_html__( 'Spacing', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'custom' ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'max' => 10, ], 'rem' => [ 'max' => 10, ], ], 'selectors' => [ '{{WRAPPER}} .elementor-post__meta-data' => 'margin-bottom: {{SIZE}}{{UNIT}};', ], 'condition' => [ $this->get_control_id( 'meta_data!' ) => [], ], ] ); $this->add_control( 'heading_excerpt_style', [ 'label' => esc_html__( 'Excerpt', 'elementor-pro' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', 'condition' => [ $this->get_control_id( 'show_excerpt' ) => 'yes', ], ] ); $this->add_control( 'excerpt_color', [ 'label' => esc_html__( 'Color', 'elementor-pro' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .elementor-post__excerpt p' => 'color: {{VALUE}};', ], 'condition' => [ $this->get_control_id( 'show_excerpt' ) => 'yes', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'excerpt_typography', 'global' => [ 'default' => Global_Typography::TYPOGRAPHY_TEXT, ], 'selector' => '{{WRAPPER}} .elementor-post__excerpt p', 'condition' => [ $this->get_control_id( 'show_excerpt' ) => 'yes', ], ] ); $this->add_responsive_control( 'excerpt_spacing', [ 'label' => esc_html__( 'Spacing', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'custom' ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'max' => 10, ], 'rem' => [ 'max' => 10, ], ], 'selectors' => [ '{{WRAPPER}} .elementor-post__excerpt' => 'margin-bottom: {{SIZE}}{{UNIT}};', ], 'condition' => [ $this->get_control_id( 'show_excerpt' ) => 'yes', ], ] ); $this->add_control( 'heading_readmore_style', [ 'label' => esc_html__( 'Read More', 'elementor-pro' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before', 'condition' => [ $this->get_control_id( 'show_read_more' ) => 'yes', ], ] ); $this->add_control( 'read_more_color', [ 'label' => esc_html__( 'Color', 'elementor-pro' ), 'type' => Controls_Manager::COLOR, 'global' => [ 'default' => Global_Colors::COLOR_ACCENT, ], 'selectors' => [ '{{WRAPPER}} .elementor-post__read-more' => 'color: {{VALUE}};', ], 'condition' => [ $this->get_control_id( 'show_read_more' ) => 'yes', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'read_more_typography', // The 'a' selector is added for specificity, for when this control's selector is used in globals CSS. 'selector' => '{{WRAPPER}} a.elementor-post__read-more', 'global' => [ 'default' => Global_Typography::TYPOGRAPHY_ACCENT, ], 'condition' => [ $this->get_control_id( 'show_read_more' ) => 'yes', ], ] ); $this->add_responsive_control( 'read_more_spacing', [ 'label' => esc_html__( 'Spacing', 'elementor-pro' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'custom' ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'max' => 10, ], 'rem' => [ 'max' => 10, ], ], 'selectors' => [ '{{WRAPPER}} .elementor-post__text' => 'margin-bottom: {{SIZE}}{{UNIT}};', ], 'condition' => [ $this->get_control_id( 'show_read_more' ) => 'yes', ], ] ); $this->end_controls_section(); } public function render() { $this->parent->query_posts(); /** @var \WP_Query $query */ $query = $this->parent->get_query(); if ( ! $query->found_posts ) { $this->handle_no_posts_found(); return; } $this->render_loop_header(); // It's the global `wp_query` it self. and the loop was started from the theme. if ( $query->in_the_loop ) { $this->current_permalink = get_permalink(); $this->render_post(); } else { while ( $query->have_posts() ) { $query->the_post(); $this->current_permalink = get_permalink(); $this->render_post(); } } wp_reset_postdata(); $this->render_loop_footer(); } public function filter_excerpt_length() { return $this->get_instance_value( 'excerpt_length' ); } public function filter_excerpt_more( $more ) { return ''; } public function get_container_class() { return 'elementor-posts--skin-' . $this->get_id(); } protected function render_thumbnail() { $thumbnail = $this->get_instance_value( 'thumbnail' ); if ( 'none' === $thumbnail && ! Plugin::elementor()->editor->is_edit_mode() ) { return; } $settings = $this->parent->get_settings(); $setting_key = $this->get_control_id( 'thumbnail_size' ); $settings[ $setting_key ] = [ 'id' => get_post_thumbnail_id(), ]; $thumbnail_html = Group_Control_Image_Size::get_attachment_image_html( $settings, $setting_key ); if ( empty( $thumbnail_html ) ) { return; } $optional_attributes_html = $this->get_optional_link_attributes_html(); ?> > get_instance_value( 'show_title' ) ) { return; } $optional_attributes_html = $this->get_optional_link_attributes_html(); $tag = $this->get_instance_value( 'title_tag' ); ?> < class="elementor-post__title"> > > get_instance_value( 'show_excerpt' ) ) { return; } add_filter( 'excerpt_more', [ $this, 'filter_excerpt_more' ], 20 ); add_filter( 'excerpt_length', [ $this, 'filter_excerpt_length' ], 20 ); ?>