File: /mnt/data/dreamssalon-wp/wp-content/plugins/dreamsalon-widgets/widgets/class-latest-blogs-two.php
<?php
namespace dreamsalonelementor\Widgets;
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;
if ( ! defined( 'ABSPATH' ) ) { exit; }
class DSLatestBlogsTwo extends Widget_Base {
public function get_name() { return 'dreamsalon-latest-blogs-two'; }
public function get_title() { return __( 'DS Latest Blogs 2', 'dreamsalon_elementor' ); }
public function get_icon() { return 'eicon-post-slider'; }
public function get_categories() { return [ 'dreamsalonelemetortheme' ]; }
protected function _register_controls() {
// Section header
$this->start_controls_section('section_header', [ 'label' => __( 'Section Header', 'dreamsalon_elementor' ) ]);
$this->add_control('badge_text', [
'label' => __( 'Badge Text', 'dreamsalon_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => 'Latest Blogs',
]);
$this->add_control('title_text', [
'label' => __( 'Title', 'dreamsalon_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => 'Latest Wellness Insights',
]);
$this->add_control('stitle_text', [
'label' => __( 'Title 2', 'dreamsalon_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => 'Discover top wellness consultants, read real reviews',
]);
$this->end_controls_section();
// Query options
$this->start_controls_section('section_query', [ 'label' => __( 'Query', 'dreamsalon_elementor' ) ]);
$this->add_control('posts_per_page', [
'label' => __( 'Number of Posts', 'dreamsalon_elementor' ),
'type' => Controls_Manager::NUMBER,
'min' => 1,
'max' => 12,
'default' => 4,
]);
$this->end_controls_section();
// View all button
$this->start_controls_section('section_button', [ 'label' => __( 'View All Button', 'dreamsalon_elementor' ) ]);
$this->add_control('view_all_text', [
'label' => __( 'Button Text', 'dreamsalon_elementor' ),
'type' => Controls_Manager::TEXT,
'default' => 'View All Articles',
]);
$this->add_control('view_all_link', [
'label' => __( 'Button Link', 'dreamsalon_elementor' ),
'type' => Controls_Manager::URL,
'default' => [ 'url' => '#' ],
]);
$this->end_controls_section();
// Background images
$this->start_controls_section('section_background', [ 'label' => __( 'Background Images', 'dreamsalon_elementor' ) ]);
$this->add_control('bg_image_one', [
'label' => __( 'Background Image 1', 'dreamsalon_elementor' ),
'type' => Controls_Manager::MEDIA,
'default' => [ 'url' => get_template_directory_uri() . '/assets/img/bg/testimonial-bg-01.png' ],
]);
$this->add_control('bg_image_two', [
'label' => __( 'Background Image 2', 'dreamsalon_elementor' ),
'type' => Controls_Manager::MEDIA,
'default' => [ 'url' => get_template_directory_uri() . '/assets/img/bg/testimonial-bg-02.png' ],
]);
$this->end_controls_section();
// Style
$this->start_controls_section(
'section_style',
[
'label' => __( 'Style', 'dreamsalon_elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'label' => __( 'Title Typography', 'dreamsalon_elementor' ),
'selector' => '{{WRAPPER}} .blog-section-six .section-header h2',
]
);
$this->end_controls_section();
}
protected function render() {
$s = $this->get_settings_for_display();
$badge = ! empty( $s['badge_text'] ) ? $s['badge_text'] : '';
$title = ! empty( $s['title_text'] ) ? $s['title_text'] : '';
$stitle = isset( $s['stitle_text'] ) ? $s['stitle_text'] : '';
$posts_number = ! empty( $s['posts_per_page'] ) ? (int) $s['posts_per_page'] : 4;
$view_text = ! empty( $s['view_all_text'] ) ? $s['view_all_text'] : '';
$view_link = ! empty( $s['view_all_link']['url'] ) ? $s['view_all_link']['url'] : '';
$bg1 = ! empty( $s['bg_image_one']['url'] ) ? $s['bg_image_one']['url'] : '';
$bg2 = ! empty( $s['bg_image_two']['url'] ) ? $s['bg_image_two']['url'] : '';
$query = new \WP_Query([
'post_type' => 'post',
'posts_per_page' => $posts_number,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
]);
?>
<section class="blog-section-six section">
<div class="container">
<div class="section-header d-flex align-items-center justify-content-between flex-wrap gap-3 wow fadeInUp" data-wow-duration="1.2s">
<div>
<?php if ( $badge ) : ?>
<span class="section-badge mb-2"><?php echo esc_html( $badge ); ?></span>
<?php endif; ?>
<?php if ( $title ) : ?>
<h2 class="mb-0 border_bottom"><?php echo esc_html( $title ); ?> <?php if ( $stitle ) : ?>
<span class="subtitle"><?php echo wp_kses_post( $stitle ); ?><span class="borderback"></span></span>
<?php endif; ?></h2>
<?php endif; ?>
</div>
<div class="d-flex align-items-center gap-2">
<button type="button" class="slick-arrow blog-prev"><i class="ti ti-chevron-left"></i></button>
<button type="button" class="slick-arrow blog-next"><i class="ti ti-chevron-right"></i></button>
</div>
</div>
<div class="blog-slider">
<?php if ( $query->have_posts() ) : ?>
<?php
$index = 0;
while ( $query->have_posts() ) :
$query->the_post();
$post_id = get_the_ID();
$permalink = get_permalink( $post_id );
$title_post= get_the_title( $post_id );
$thumb_url = get_the_post_thumbnail_url( $post_id, 'large' );
$author_id = get_the_author_meta( 'ID' );
$avatar = get_avatar_url( $author_id, [ 'size' => 96 ] );
$day = get_the_date( 'd', $post_id );
$mon = get_the_date( 'M', $post_id );
$cats = get_the_category( $post_id );
$cat = ! empty( $cats ) ? $cats[0] : null;
$content = get_post_field( 'post_content', $post_id );
$word_count = $content ? str_word_count( wp_strip_all_tags( $content ) ) : 0;
$read_minutes = max( 1, (int) ceil( $word_count / 200 ) );
// animation durations from original HTML pattern
$durations = [ '1.2s', '1.3s', '1.4s', '1.2s' ];
$delays = [ '0.2s', '0.4s', '0.6s', '0.2s' ];
$pos = $index % 4;
$wow_dur = $durations[ $pos ];
$wow_delay = $delays[ $pos ];
?>
<div class="blog-item-six flex-fill wow fadeInUp" data-wow-duration="<?php echo esc_attr( $wow_dur ); ?>" data-wow-delay="<?php echo esc_attr( $wow_delay ); ?>">
<div class="blog-img">
<a href="<?php echo esc_url( $permalink ); ?>">
<?php if ( $thumb_url ) : ?>
<img src="<?php echo esc_url( $thumb_url ); ?>" class="img-fluid" alt="<?php echo esc_attr( $title_post ); ?>">
<?php endif; ?>
</a>
<?php if ( $avatar ) : ?>
<a href="<?php echo esc_url( get_author_posts_url( $author_id ) ); ?>" class="avatar avatar-rounded">
<img src="<?php echo esc_url( $avatar ); ?>" class="img-fluid" alt="<?php echo esc_attr( get_the_author() ); ?>">
</a>
<?php endif; ?>
<div class="blog-date">
<p><?php echo esc_html( $day ); ?><span><?php echo esc_html( $mon ); ?></span></p>
</div>
</div>
<div class="blog-content">
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3 mb-3">
<div>
<?php if ( $cat ) : ?>
<a href="<?php echo esc_url( get_category_link( $cat->term_id ) ); ?>" class="badge bg-dark"><?php echo esc_html( $cat->name ); ?></a>
<?php endif; ?>
</div>
<p class="mb-0"><?php echo esc_html( $read_minutes . ' Mins to read' ); ?></p>
</div>
<h3 class="mb-0"><a href="<?php echo esc_url( $permalink ); ?>"><?php echo esc_html( $title_post ); ?></a></h3>
</div>
</div>
<?php
$index++;
endwhile;
wp_reset_postdata();
?>
<?php else : ?>
<p><?php esc_html_e( 'No blog posts found.', 'dreamsalon_elementor' ); ?></p>
<?php endif; ?>
</div>
<!-- End Slider -->
<?php if ( $view_text && $view_link ) : ?>
<div class="text-center view-more">
<a href="<?php echo esc_url( $view_link ); ?>" class="btn btn-dark d-inline-flex align-items-center rounded-pill"><?php echo esc_html( $view_text ); ?><i class="ti ti-chevron-right ms-1"></i></a>
</div>
<?php endif; ?>
</div>
<?php if ( $bg1 ) : ?>
<img src="<?php echo esc_url( $bg1 ); ?>" alt="bg" class="img-fluid blog-bg-01">
<?php endif; ?>
<?php if ( $bg2 ) : ?>
<img src="<?php echo esc_url( $bg2 ); ?>" alt="bg" class="img-fluid blog-bg-02">
<?php endif; ?>
</section>
<?php
}
}