Skip to content

Instantly share code, notes, and snippets.

@gicolek
Created May 31, 2022 12:37
Show Gist options
  • Save gicolek/2f6ef2fff7152a5e9d08b0b0a29685db to your computer and use it in GitHub Desktop.
Save gicolek/2f6ef2fff7152a5e9d08b0b0a29685db to your computer and use it in GitHub Desktop.
Custom Elementor Widget Part 2
<?php
// make sure this line is here, the Widget Base belongs to Elementor Namespace
namespace Elementor;
if ( !defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// Extend the \Elementor\Widget_Base class
class My_Widget_Custom_Blog_Loop extends Widget_Base {
// name of the widget, used internally
public function get_name(){
return esc_html__( 'prefix-custom-blog-loop', 'my-widget' );
}
// title of the widget displayed in the Elementor Widget Selection screen
public function get_title(){
return esc_html__( 'Custom blog loop', 'my-widget' );
}
// icon of the widget displayed in the Elementor Widget Selection screen
public function get_icon(){
return esc_html__( 'eicon-post', 'my-widget' );
}
public function get_custom_help_url(){
return 'https://wp-doin.com';
}
// the widget will fall under the general tab on the Elementor Widget Selection screen
public function get_categories(){
return [ 'general' ];
}
// used for search filtering
public function get_keywords(){
return [ 'posts', 'loop' ];
}
// the method will register a custom widget script residing within elementor-widgets/js/ directory of the active child theme and load it
public function get_script_depends(){
wp_register_script( 'custom-widget-script', get_stylesheet_directory_uri() . '/elementor-widgets/js/custom-widget-script.js' );
return [
'custom-widget-script',
];
}
// the method will register a custom widget style residing within elementor-widgets/css/ directory of the active child theme and load it
public function get_style_depends(){
wp_register_style( 'custom-widget-style', get_stylesheet_directory_uri() . '/elementor-widgets/css/custom-widget-style.css' );
return [
'custom-widget-style',
];
}
// register the widget controls, say input fields, that can be fetched later on and used to dynamically alter content
protected function _register_controls(){
// title of the section
$this->start_controls_section(
'section_title',
[
'label' => __( 'Custom blog loop settings', 'my-widget' ),
]
);
// a sample text control
$this->add_control(
'title',
[
'type' => \Elementor\Controls_Manager::TEXT,
'label' => esc_html__( 'Title', 'my-widget' ),
'placeholder' => esc_html__( 'Displays above the area.', 'my-widget' ),
]
);
// a sample select control
$this->add_control(
'posts_per_page',
[
'type' => \Elementor\Controls_Manager::SELECT,
'label' => esc_html__( 'Posts per page', 'my-widget' ),
'options' => [
'-1' => esc_html__( 'All', 'my-widget' ),
'5' => esc_html__( '5', 'my-widget' ),
'10' => esc_html__( '10', 'my-widget' ),
],
'default' => '5',
]
);
$this->end_controls_section();
// style controls, found under Style Tab of our Widget
$this->start_controls_section(
'section_title_style',
[
'label' => __( 'Content styles', 'my-widget' ),
'tab' => \Elementor\Controls_Manager::TAB_STYLE,
]
);
// utility to control our headings color
$this->add_control(
'heading_color',
[
'label' => esc_html__( 'Heading color', 'my-widget' ),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#fff',
'selectors' => [
'{{WRAPPER}} h2' => 'color: {{VALUE}}', // this line will modify the color of all h2 elements of our widget
],
]
);
// utility to control our main heading's color
$this->add_control(
'title_color',
[
'label' => esc_html__( 'Post title color', 'my-widget' ),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#fff',
'selectors' => [
'{{WRAPPER}} h3' => 'color: {{VALUE}}',
],
]
);
// utility to control posts text color
$this->add_control(
'text_color',
[
'label' => esc_html__( 'Post text color', 'my-widget' ),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#fff',
'selectors' => [
'{{WRAPPER}} div.c-post__content p' => 'color: {{VALUE}}',
],
]
);
// utility to control the direction of our flex wrapper
$this->add_control(
'flex_direction',
[
'label' => esc_html__( 'Flex direction', 'my-widget' ),
'type' => \Elementor\Controls_Manager::SELECT,
'options' => [
'row' => esc_html__( 'Row', 'my-widget' ),
'column' => esc_html__( 'Column', 'my-widget' ),
],
'default' => 'row',
'selectors' => [
'{{WRAPPER}} div.c-posts' => 'flex-direction: {{VALUE}}',
],
]
);
// control the maximum width of each posts, displays if flex_direction is row
$this->add_control(
'post_max_width_column',
[
'label' => esc_html__( 'Posts max width', 'my-plugin' ),
'type' => \Elementor\Controls_Manager::SLIDER,
'size_units' => [ 'px', '%' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
'step' => 1,
],
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'unit' => '%',
'size' => 100,
],
'selectors' => [
'{{WRAPPER}} .c-post' => 'max-width: {{SIZE}}{{UNIT}}; flex: 0 0 {{SIZE}}{{UNIT}};',
],
'condition' => [
'flex_direction' => 'column', // this is what controls the dynamic display of our element
],
]
);
// control the maximum width of each posts, displays if flex_direction is column
$this->add_control(
'post_max_width_row',
[
'label' => esc_html__( 'Posts max width', 'my-plugin' ),
'type' => \Elementor\Controls_Manager::SLIDER,
'size_units' => [ 'px', '%' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
'step' => 1,
],
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'unit' => '%',
'size' => 25,
],
'selectors' => [
'{{WRAPPER}} .c-post' => 'max-width: {{SIZE}}{{UNIT}}; flex: 0 0 {{SIZE}}{{UNIT}};',
],
'condition' => [
'flex_direction' => 'row',
],
]
);
// margin between the posts in case of row (top and bottom)
$this->add_control(
'margin_between_posts_row',
[
'label' => esc_html__( 'Margin between posts', 'my-plugin' ),
'description' => esc_html__( 'Adds left and right margin.', 'my-plugin' ),
'type' => \Elementor\Controls_Manager::SLIDER,
'size_units' => [ 'px', '%' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
'step' => 5,
],
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'unit' => 'px',
'size' => 10,
],
'selectors' => [
'{{WRAPPER}} .c-post' => 'margin: 0 {{SIZE}}{{UNIT}} 0 {{SIZE}}{{UNIT}};',
],
'condition' => [
'flex_direction' => 'row',
],
]
);
// margin between the posts in case of column (left and right)
$this->add_control(
'margin_between_posts_column',
[
'label' => esc_html__( 'Margin between posts', 'my-plugin' ),
'description' => esc_html__( 'Adds top and bottom margin.', 'my-plugin' ),
'type' => \Elementor\Controls_Manager::SLIDER,
'size_units' => [ 'px', '%' ],
'range' => [
'px' => [
'min' => 0,
'max' => 1000,
'step' => 5,
],
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'unit' => 'px',
'size' => 10,
],
'selectors' => [
'{{WRAPPER}} .c-post' => 'margin: {{SIZE}}{{UNIT}} 0 {{SIZE}}{{UNIT}} 0;',
],
'condition' => [
'flex_direction' => 'column',
],
]
);
$this->end_controls_section();
}
// method that displays the widget, we will fetch the saved values and use them to alter our widget's display
protected function render(){
// get the settings
$settings = $this->get_settings_for_display();
// get the title from the settings
$title = $settings['title'];
// get the posts per page from the settings
$posts_per_page = $settings['posts_per_page'];
// get the list
$list = $settings['list'];
// run the code iff both of these are set
if ( isset( $title ) and isset( $posts_per_page ) ):
$args = array(
'posts_per_page' => $posts_per_page,
'post_type' => 'post',
);
$custom_posts = new \WP_Query( $args );
if ( $custom_posts->have_posts() ):
?>
<h2><?php echo $title; ?></h2>
<div class="c-posts">
<?php
while ( $custom_posts->have_posts() ):
$custom_posts->the_post();
?>
<div class="c-post">
<h3><?php the_title(); ?></h3>
<div class="c-post__content">
<?php the_content(); ?>
</div>
</div>
<?php
endwhile;
wp_reset_postdata();
?>
</div>
<?php
endif;
endif;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment